• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 #ifndef ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_
18 #define ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_
19 
20 #include <android-base/logging.h>
21 
22 #include "base/globals.h"
23 #include "base/macros.h"
24 
25 typedef uint8_t uint4_t;
26 typedef int8_t int4_t;
27 
28 namespace art {
29 
30 class DexFile;
31 
32 enum {
33   kNumPackedOpcodes = 0x100
34 };
35 
36 class Instruction {
37  public:
38   // NOP-encoded switch-statement signatures.
39   enum Signatures {
40     kPackedSwitchSignature = 0x0100,
41     kSparseSwitchSignature = 0x0200,
42     kArrayDataSignature = 0x0300,
43   };
44 
45   struct PACKED(4) PackedSwitchPayload {
46     const uint16_t ident;
47     const uint16_t case_count;
48     const int32_t first_key;
49     const int32_t targets[];
50 
51    private:
52     DISALLOW_COPY_AND_ASSIGN(PackedSwitchPayload);
53   };
54 
55   struct PACKED(4) SparseSwitchPayload {
56     const uint16_t ident;
57     const uint16_t case_count;
58     const int32_t keys_and_targets[];
59 
60    public:
GetKeysSparseSwitchPayload61     const int32_t* GetKeys() const {
62       return keys_and_targets;
63     }
64 
GetTargetsSparseSwitchPayload65     const int32_t* GetTargets() const {
66       return keys_and_targets + case_count;
67     }
68 
69    private:
70     DISALLOW_COPY_AND_ASSIGN(SparseSwitchPayload);
71   };
72 
73   struct PACKED(4) ArrayDataPayload {
74     const uint16_t ident;
75     const uint16_t element_width;
76     const uint32_t element_count;
77     const uint8_t data[];
78 
79    private:
80     DISALLOW_COPY_AND_ASSIGN(ArrayDataPayload);
81   };
82 
83   enum Code {  // private marker to avoid generate-operator-out.py from processing.
84 #define INSTRUCTION_ENUM(opcode, cname, p, f, i, a, e, v) cname = (opcode),
85 #include "dex_instruction_list.h"
86     DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM)
87 #undef DEX_INSTRUCTION_LIST
88 #undef INSTRUCTION_ENUM
89     RSUB_INT_LIT16 = RSUB_INT,
90   };
91 
92   enum Format : uint8_t {
93     k10x,  // op
94     k12x,  // op vA, vB
95     k11n,  // op vA, #+B
96     k11x,  // op vAA
97     k10t,  // op +AA
98     k20t,  // op +AAAA
99     k22x,  // op vAA, vBBBB
100     k21t,  // op vAA, +BBBB
101     k21s,  // op vAA, #+BBBB
102     k21h,  // op vAA, #+BBBB00000[00000000]
103     k21c,  // op vAA, thing@BBBB
104     k23x,  // op vAA, vBB, vCC
105     k22b,  // op vAA, vBB, #+CC
106     k22t,  // op vA, vB, +CCCC
107     k22s,  // op vA, vB, #+CCCC
108     k22c,  // op vA, vB, thing@CCCC
109     k32x,  // op vAAAA, vBBBB
110     k30t,  // op +AAAAAAAA
111     k31t,  // op vAA, +BBBBBBBB
112     k31i,  // op vAA, #+BBBBBBBB
113     k31c,  // op vAA, thing@BBBBBBBB
114     k35c,  // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)
115     k3rc,  // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
116 
117     // op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH (A: count)
118     // format: AG op BBBB FEDC HHHH
119     k45cc,
120 
121     // op {VCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH (AA: count)
122     // format: AA op BBBB CCCC HHHH
123     k4rcc,  // op {VCCCC .. v(CCCC+AA-1)}, meth@BBBB, proto@HHHH (AA: count)
124 
125     k51l,  // op vAA, #+BBBBBBBBBBBBBBBB
126     kInvalidFormat,
127   };
128 
129   enum IndexType : uint8_t {
130     kIndexUnknown = 0,
131     kIndexNone,               // has no index
132     kIndexTypeRef,            // type reference index
133     kIndexStringRef,          // string reference index
134     kIndexMethodRef,          // method reference index
135     kIndexFieldRef,           // field reference index
136     kIndexFieldOffset,        // field offset (for static linked fields)
137     kIndexVtableOffset,       // vtable offset (for static linked methods)
138     kIndexMethodAndProtoRef,  // method and a proto reference index (for invoke-polymorphic)
139     kIndexCallSiteRef,        // call site reference index
140     kIndexMethodHandleRef,    // constant method handle reference index
141     kIndexProtoRef,           // prototype reference index
142   };
143 
144   enum Flags : uint8_t {
145     kBranch              = 0x01,  // conditional or unconditional branch
146     kContinue            = 0x02,  // flow can continue to next statement
147     kSwitch              = 0x04,  // switch statement
148     kThrow               = 0x08,  // could cause an exception to be thrown
149     kReturn              = 0x10,  // returns, no additional statements
150     kInvoke              = 0x20,  // a flavor of invoke
151     kUnconditional       = 0x40,  // unconditional branch
152     kExperimental        = 0x80,  // is an experimental opcode
153   };
154 
155   // Old flags. Keeping them around in case we might need them again some day.
156   enum ExtendedFlags : uint32_t {
157     kAdd                 = 0x0000080,  // addition
158     kSubtract            = 0x0000100,  // subtract
159     kMultiply            = 0x0000200,  // multiply
160     kDivide              = 0x0000400,  // division
161     kRemainder           = 0x0000800,  // remainder
162     kAnd                 = 0x0001000,  // and
163     kOr                  = 0x0002000,  // or
164     kXor                 = 0x0004000,  // xor
165     kShl                 = 0x0008000,  // shl
166     kShr                 = 0x0010000,  // shr
167     kUshr                = 0x0020000,  // ushr
168     kCast                = 0x0040000,  // cast
169     kStore               = 0x0080000,  // store opcode
170     kLoad                = 0x0100000,  // load opcode
171     kClobber             = 0x0200000,  // clobbers memory in a big way (not just a write)
172     kRegCFieldOrConstant = 0x0400000,  // is the third virtual register a field or literal constant (vC)
173     kRegBFieldOrConstant = 0x0800000,  // is the second virtual register a field or literal constant (vB)
174   };
175 
176   enum VerifyFlag : uint32_t {
177     kVerifyNothing            = 0x0000000,
178     kVerifyRegA               = 0x0000001,
179     kVerifyRegAWide           = 0x0000002,
180     kVerifyRegB               = 0x0000004,
181     kVerifyRegBField          = 0x0000008,
182     kVerifyRegBMethod         = 0x0000010,
183     kVerifyRegBNewInstance    = 0x0000020,
184     kVerifyRegBString         = 0x0000040,
185     kVerifyRegBType           = 0x0000080,
186     kVerifyRegBWide           = 0x0000100,
187     kVerifyRegC               = 0x0000200,
188     kVerifyRegCField          = 0x0000400,
189     kVerifyRegCNewArray       = 0x0000800,
190     kVerifyRegCType           = 0x0001000,
191     kVerifyRegCWide           = 0x0002000,
192     kVerifyArrayData          = 0x0004000,
193     kVerifyBranchTarget       = 0x0008000,
194     kVerifySwitchTargets      = 0x0010000,
195     kVerifyVarArg             = 0x0020000,
196     kVerifyVarArgNonZero      = 0x0040000,
197     kVerifyVarArgRange        = 0x0080000,
198     kVerifyVarArgRangeNonZero = 0x0100000,
199     kVerifyRuntimeOnly        = 0x0200000,
200     kVerifyError              = 0x0400000,
201     kVerifyRegHPrototype      = 0x0800000,
202     kVerifyRegBCallSite       = 0x1000000,
203     kVerifyRegBMethodHandle   = 0x2000000,
204     kVerifyRegBPrototype      = 0x4000000,
205   };
206 
207   // Collect the enums in a struct for better locality.
208   struct InstructionDescriptor {
209     uint32_t verify_flags;         // Set of VerifyFlag.
210     Format format;
211     IndexType index_type;
212     uint8_t flags;                 // Set of Flags.
213     int8_t size_in_code_units;
214   };
215 
216   static constexpr uint32_t kMaxVarArgRegs = 5;
217 
218   static constexpr bool kHaveExperimentalInstructions = false;
219 
220   // Returns the size (in 2 byte code units) of this instruction.
SizeInCodeUnits()221   size_t SizeInCodeUnits() const {
222     int8_t result = kInstructionDescriptors[Opcode()].size_in_code_units;
223     if (UNLIKELY(result < 0)) {
224       return SizeInCodeUnitsComplexOpcode();
225     } else {
226       return static_cast<size_t>(result);
227     }
228   }
229 
230   // Returns the size (in 2 byte code units) of the given instruction format.
231   ALWAYS_INLINE static constexpr size_t SizeInCodeUnits(Format format);
232 
233   // Code units required to calculate the size of the instruction.
CodeUnitsRequiredForSizeComputation()234   size_t CodeUnitsRequiredForSizeComputation() const {
235     const int8_t result = kInstructionDescriptors[Opcode()].size_in_code_units;
236     return UNLIKELY(result < 0) ? CodeUnitsRequiredForSizeOfComplexOpcode() : 1;
237   }
238 
239   // Reads an instruction out of the stream at the specified address.
At(const uint16_t * code)240   static const Instruction* At(const uint16_t* code) {
241     DCHECK(code != nullptr);
242     return reinterpret_cast<const Instruction*>(code);
243   }
244 
245   // Reads an instruction out of the stream from the current address plus an offset.
RelativeAt(int32_t offset)246   const Instruction* RelativeAt(int32_t offset) const WARN_UNUSED {
247     return At(reinterpret_cast<const uint16_t*>(this) + offset);
248   }
249 
250   // Returns a pointer to the next instruction in the stream.
Next()251   const Instruction* Next() const {
252     return RelativeAt(SizeInCodeUnits());
253   }
254 
255   // Returns a pointer to the instruction after this 1xx instruction in the stream.
Next_1xx()256   const Instruction* Next_1xx() const {
257     DCHECK(FormatOf(Opcode()) >= k10x && FormatOf(Opcode()) <= k10t);
258     return RelativeAt(1);
259   }
260 
261   // Returns a pointer to the instruction after this 2xx instruction in the stream.
Next_2xx()262   const Instruction* Next_2xx() const {
263     DCHECK(FormatOf(Opcode()) >= k20t && FormatOf(Opcode()) <= k22c);
264     return RelativeAt(2);
265   }
266 
267   // Returns a pointer to the instruction after this 3xx instruction in the stream.
Next_3xx()268   const Instruction* Next_3xx() const {
269     DCHECK(FormatOf(Opcode()) >= k32x && FormatOf(Opcode()) <= k3rc);
270     return RelativeAt(3);
271   }
272 
273   // Returns a pointer to the instruction after this 4xx instruction in the stream.
Next_4xx()274   const Instruction* Next_4xx() const {
275     DCHECK(FormatOf(Opcode()) >= k45cc && FormatOf(Opcode()) <= k4rcc);
276     return RelativeAt(4);
277   }
278 
279   // Returns a pointer to the instruction after this 51l instruction in the stream.
Next_51l()280   const Instruction* Next_51l() const {
281     DCHECK(FormatOf(Opcode()) == k51l);
282     return RelativeAt(5);
283   }
284 
285   // Returns the name of this instruction's opcode.
Name()286   const char* Name() const {
287     return Instruction::Name(Opcode());
288   }
289 
290   // Returns the name of the given opcode.
Name(Code opcode)291   static const char* Name(Code opcode) {
292     return kInstructionNames[opcode];
293   }
294 
295   // VRegA
296   bool HasVRegA() const;
297   ALWAYS_INLINE int32_t VRegA() const;
298   ALWAYS_INLINE int32_t VRegA(Format format, uint16_t inst_data) const;
299 
VRegA_10t()300   int8_t VRegA_10t() const {
301     return VRegA_10t(Fetch16(0));
302   }
VRegA_10x()303   uint8_t VRegA_10x() const {
304     return VRegA_10x(Fetch16(0));
305   }
VRegA_11n()306   uint4_t VRegA_11n() const {
307     return VRegA_11n(Fetch16(0));
308   }
VRegA_11x()309   uint8_t VRegA_11x() const {
310     return VRegA_11x(Fetch16(0));
311   }
VRegA_12x()312   uint4_t VRegA_12x() const {
313     return VRegA_12x(Fetch16(0));
314   }
315   int16_t VRegA_20t() const;
VRegA_21c()316   uint8_t VRegA_21c() const {
317     return VRegA_21c(Fetch16(0));
318   }
VRegA_21h()319   uint8_t VRegA_21h() const {
320     return VRegA_21h(Fetch16(0));
321   }
VRegA_21s()322   uint8_t VRegA_21s() const {
323     return VRegA_21s(Fetch16(0));
324   }
VRegA_21t()325   uint8_t VRegA_21t() const {
326     return VRegA_21t(Fetch16(0));
327   }
VRegA_22b()328   uint8_t VRegA_22b() const {
329     return VRegA_22b(Fetch16(0));
330   }
VRegA_22c()331   uint4_t VRegA_22c() const {
332     return VRegA_22c(Fetch16(0));
333   }
VRegA_22s()334   uint4_t VRegA_22s() const {
335     return VRegA_22s(Fetch16(0));
336   }
VRegA_22t()337   uint4_t VRegA_22t() const {
338     return VRegA_22t(Fetch16(0));
339   }
VRegA_22x()340   uint8_t VRegA_22x() const {
341     return VRegA_22x(Fetch16(0));
342   }
VRegA_23x()343   uint8_t VRegA_23x() const {
344     return VRegA_23x(Fetch16(0));
345   }
346   int32_t VRegA_30t() const;
VRegA_31c()347   uint8_t VRegA_31c() const {
348     return VRegA_31c(Fetch16(0));
349   }
VRegA_31i()350   uint8_t VRegA_31i() const {
351     return VRegA_31i(Fetch16(0));
352   }
VRegA_31t()353   uint8_t VRegA_31t() const {
354     return VRegA_31t(Fetch16(0));
355   }
356   uint16_t VRegA_32x() const;
VRegA_35c()357   uint4_t VRegA_35c() const {
358     return VRegA_35c(Fetch16(0));
359   }
VRegA_3rc()360   uint8_t VRegA_3rc() const {
361     return VRegA_3rc(Fetch16(0));
362   }
VRegA_51l()363   uint8_t VRegA_51l() const {
364     return VRegA_51l(Fetch16(0));
365   }
VRegA_45cc()366   uint4_t VRegA_45cc() const {
367     return VRegA_45cc(Fetch16(0));
368   }
VRegA_4rcc()369   uint8_t VRegA_4rcc() const {
370     return VRegA_4rcc(Fetch16(0));
371   }
372 
373   // The following methods return the vA operand for various instruction formats. The "inst_data"
374   // parameter holds the first 16 bits of instruction which the returned value is decoded from.
375   int8_t VRegA_10t(uint16_t inst_data) const;
376   uint8_t VRegA_10x(uint16_t inst_data) const;
377   uint4_t VRegA_11n(uint16_t inst_data) const;
378   uint8_t VRegA_11x(uint16_t inst_data) const;
379   uint4_t VRegA_12x(uint16_t inst_data) const;
380   uint8_t VRegA_21c(uint16_t inst_data) const;
381   uint8_t VRegA_21h(uint16_t inst_data) const;
382   uint8_t VRegA_21s(uint16_t inst_data) const;
383   uint8_t VRegA_21t(uint16_t inst_data) const;
384   uint8_t VRegA_22b(uint16_t inst_data) const;
385   uint4_t VRegA_22c(uint16_t inst_data) const;
386   uint4_t VRegA_22s(uint16_t inst_data) const;
387   uint4_t VRegA_22t(uint16_t inst_data) const;
388   uint8_t VRegA_22x(uint16_t inst_data) const;
389   uint8_t VRegA_23x(uint16_t inst_data) const;
390   uint8_t VRegA_31c(uint16_t inst_data) const;
391   uint8_t VRegA_31i(uint16_t inst_data) const;
392   uint8_t VRegA_31t(uint16_t inst_data) const;
393   uint4_t VRegA_35c(uint16_t inst_data) const;
394   uint8_t VRegA_3rc(uint16_t inst_data) const;
395   uint8_t VRegA_51l(uint16_t inst_data) const;
396   uint4_t VRegA_45cc(uint16_t inst_data) const;
397   uint8_t VRegA_4rcc(uint16_t inst_data) const;
398 
399   // VRegB
400   bool HasVRegB() const;
401   ALWAYS_INLINE int32_t VRegB() const;
402   ALWAYS_INLINE int32_t VRegB(Format format, uint16_t inst_data) const;
403 
404   bool HasWideVRegB() const;
405   uint64_t WideVRegB() const;
406 
VRegB_11n()407   int4_t VRegB_11n() const {
408     return VRegB_11n(Fetch16(0));
409   }
VRegB_12x()410   uint4_t VRegB_12x() const {
411     return VRegB_12x(Fetch16(0));
412   }
413   uint16_t VRegB_21c() const;
414   uint16_t VRegB_21h() const;
415   int16_t VRegB_21s() const;
416   int16_t VRegB_21t() const;
417   uint8_t VRegB_22b() const;
VRegB_22c()418   uint4_t VRegB_22c() const {
419     return VRegB_22c(Fetch16(0));
420   }
VRegB_22s()421   uint4_t VRegB_22s() const {
422     return VRegB_22s(Fetch16(0));
423   }
VRegB_22t()424   uint4_t VRegB_22t() const {
425     return VRegB_22t(Fetch16(0));
426   }
427   uint16_t VRegB_22x() const;
428   uint8_t VRegB_23x() const;
429   uint32_t VRegB_31c() const;
430   int32_t VRegB_31i() const;
431   int32_t VRegB_31t() const;
432   uint16_t VRegB_32x() const;
433   uint16_t VRegB_35c() const;
434   uint16_t VRegB_3rc() const;
435   uint64_t VRegB_51l() const;  // vB_wide
436   uint16_t VRegB_45cc() const;
437   uint16_t VRegB_4rcc() const;
438 
439   // The following methods return the vB operand for all instruction formats where it is encoded in
440   // the first 16 bits of instruction. The "inst_data" parameter holds these 16 bits. The returned
441   // value is decoded from it.
442   int4_t VRegB_11n(uint16_t inst_data) const;
443   uint4_t VRegB_12x(uint16_t inst_data) const;
444   uint4_t VRegB_22c(uint16_t inst_data) const;
445   uint4_t VRegB_22s(uint16_t inst_data) const;
446   uint4_t VRegB_22t(uint16_t inst_data) const;
447 
448   // VRegC
449   bool HasVRegC() const;
450   ALWAYS_INLINE int32_t VRegC() const;
451   ALWAYS_INLINE int32_t VRegC(Format format) const;
452 
453   int8_t VRegC_22b() const;
454   uint16_t VRegC_22c() const;
455   int16_t VRegC_22s() const;
456   int16_t VRegC_22t() const;
457   uint8_t VRegC_23x() const;
458   uint4_t VRegC_35c() const;
459   uint16_t VRegC_3rc() const;
460   uint4_t VRegC_45cc() const;
461   uint16_t VRegC_4rcc() const;
462 
463 
464   // VRegH
465   bool HasVRegH() const;
466   int32_t VRegH() const;
467   uint16_t VRegH_45cc() const;
468   uint16_t VRegH_4rcc() const;
469 
470   // Fills the given array with the 'arg' array of the instruction.
471   bool HasVarArgs() const;
472   uint32_t GetVarArgs(uint32_t args[kMaxVarArgRegs], uint16_t inst_data) const;
GetVarArgs(uint32_t args[kMaxVarArgRegs])473   uint32_t GetVarArgs(uint32_t args[kMaxVarArgRegs]) const {
474     return GetVarArgs(args, Fetch16(0));
475   }
476 
477   // Returns the opcode field of the instruction. The given "inst_data" parameter must be the first
478   // 16 bits of instruction.
Opcode(uint16_t inst_data)479   Code Opcode(uint16_t inst_data) const {
480     DCHECK_EQ(inst_data, Fetch16(0));
481     return static_cast<Code>(inst_data & 0xFF);
482   }
483 
484   // Returns the opcode field of the instruction from the first 16 bits of instruction.
Opcode()485   Code Opcode() const {
486     return Opcode(Fetch16(0));
487   }
488 
SetOpcode(Code opcode)489   void SetOpcode(Code opcode) {
490     DCHECK_LT(static_cast<uint16_t>(opcode), 256u);
491     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
492     insns[0] = (insns[0] & 0xff00) | static_cast<uint16_t>(opcode);
493   }
494 
SetVRegA_10x(uint8_t val)495   void SetVRegA_10x(uint8_t val) {
496     DCHECK(FormatOf(Opcode()) == k10x);
497     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
498     insns[0] = (val << 8) | (insns[0] & 0x00ff);
499   }
500 
SetVRegB_3rc(uint16_t val)501   void SetVRegB_3rc(uint16_t val) {
502     DCHECK(FormatOf(Opcode()) == k3rc);
503     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
504     insns[1] = val;
505   }
506 
SetVRegB_35c(uint16_t val)507   void SetVRegB_35c(uint16_t val) {
508     DCHECK(FormatOf(Opcode()) == k35c);
509     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
510     insns[1] = val;
511   }
512 
SetVRegC_22c(uint16_t val)513   void SetVRegC_22c(uint16_t val) {
514     DCHECK(FormatOf(Opcode()) == k22c);
515     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
516     insns[1] = val;
517   }
518 
SetVRegA_21c(uint8_t val)519   void SetVRegA_21c(uint8_t val) {
520     DCHECK(FormatOf(Opcode()) == k21c);
521     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
522     insns[0] = (val << 8) | (insns[0] & 0x00ff);
523   }
524 
SetVRegB_21c(uint16_t val)525   void SetVRegB_21c(uint16_t val) {
526     DCHECK(FormatOf(Opcode()) == k21c);
527     uint16_t* insns = reinterpret_cast<uint16_t*>(this);
528     insns[1] = val;
529   }
530 
531   // Returns the format of the given opcode.
FormatOf(Code opcode)532   static Format FormatOf(Code opcode) {
533     return kInstructionDescriptors[opcode].format;
534   }
535 
536   // Returns the index type of the given opcode.
IndexTypeOf(Code opcode)537   static IndexType IndexTypeOf(Code opcode) {
538     return kInstructionDescriptors[opcode].index_type;
539   }
540 
541   // Returns the flags for the given opcode.
FlagsOf(Code opcode)542   static uint8_t FlagsOf(Code opcode) {
543     return kInstructionDescriptors[opcode].flags;
544   }
545 
546   // Return the verify flags for the given opcode.
VerifyFlagsOf(Code opcode)547   static uint32_t VerifyFlagsOf(Code opcode) {
548     return kInstructionDescriptors[opcode].verify_flags;
549   }
550 
551   // Returns true if this instruction is a branch.
IsBranch()552   bool IsBranch() const {
553     return (kInstructionDescriptors[Opcode()].flags & kBranch) != 0;
554   }
555 
556   // Returns true if this instruction is a unconditional branch.
IsUnconditional()557   bool IsUnconditional() const {
558     return (kInstructionDescriptors[Opcode()].flags & kUnconditional) != 0;
559   }
560 
561   // Returns the branch offset if this instruction is a branch.
562   int32_t GetTargetOffset() const;
563 
564   // Returns true if the instruction allows control flow to go to the following instruction.
565   bool CanFlowThrough() const;
566 
567   // Returns true if the instruction is a quickened instruction.
IsQuickened()568   bool IsQuickened() const {
569     return (kInstructionDescriptors[Opcode()].index_type == kIndexFieldOffset) ||
570         (kInstructionDescriptors[Opcode()].index_type == kIndexVtableOffset);
571   }
572 
573   // Returns true if this instruction is a switch.
IsSwitch()574   bool IsSwitch() const {
575     return (kInstructionDescriptors[Opcode()].flags & kSwitch) != 0;
576   }
577 
578   // Returns true if this instruction can throw.
IsThrow()579   bool IsThrow() const {
580     return (kInstructionDescriptors[Opcode()].flags & kThrow) != 0;
581   }
582 
583   // Determine if the instruction is any of 'return' instructions.
IsReturn()584   bool IsReturn() const {
585     return (kInstructionDescriptors[Opcode()].flags & kReturn) != 0;
586   }
587 
588   // Determine if this instruction ends execution of its basic block.
IsBasicBlockEnd()589   bool IsBasicBlockEnd() const {
590     return IsBranch() || IsReturn() || Opcode() == THROW;
591   }
592 
593   // Determine if this instruction is an invoke.
IsInvoke()594   bool IsInvoke() const {
595     return (kInstructionDescriptors[Opcode()].flags & kInvoke) != 0;
596   }
597 
598   // Determine if this instruction is experimental.
IsExperimental()599   bool IsExperimental() const {
600     return (kInstructionDescriptors[Opcode()].flags & kExperimental) != 0;
601   }
602 
GetVerifyTypeArgumentA()603   int GetVerifyTypeArgumentA() const {
604     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegA | kVerifyRegAWide));
605   }
606 
GetVerifyTypeArgumentB()607   int GetVerifyTypeArgumentB() const {
608     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegB | kVerifyRegBField |
609         kVerifyRegBMethod | kVerifyRegBNewInstance | kVerifyRegBString | kVerifyRegBType |
610         kVerifyRegBWide));
611   }
612 
GetVerifyTypeArgumentC()613   int GetVerifyTypeArgumentC() const {
614     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyRegC | kVerifyRegCField |
615         kVerifyRegCNewArray | kVerifyRegCType | kVerifyRegCWide));
616   }
617 
GetVerifyTypeArgumentH()618   int GetVerifyTypeArgumentH() const {
619     return (kInstructionDescriptors[Opcode()].verify_flags & kVerifyRegHPrototype);
620   }
621 
GetVerifyExtraFlags()622   int GetVerifyExtraFlags() const {
623     return (kInstructionDescriptors[Opcode()].verify_flags & (kVerifyArrayData |
624         kVerifyBranchTarget | kVerifySwitchTargets | kVerifyVarArg | kVerifyVarArgNonZero |
625         kVerifyVarArgRange | kVerifyVarArgRangeNonZero | kVerifyError));
626   }
627 
GetVerifyIsRuntimeOnly()628   bool GetVerifyIsRuntimeOnly() const {
629     return (kInstructionDescriptors[Opcode()].verify_flags & kVerifyRuntimeOnly) != 0;
630   }
631 
632   // Get the dex PC of this instruction as a offset in code units from the beginning of insns.
GetDexPc(const uint16_t * insns)633   uint32_t GetDexPc(const uint16_t* insns) const {
634     return (reinterpret_cast<const uint16_t*>(this) - insns);
635   }
636 
637   // Dump decoded version of instruction
638   std::string DumpString(const DexFile*) const;
639 
640   // Dump code_units worth of this instruction, padding to code_units for shorter instructions
641   std::string DumpHex(size_t code_units) const;
642 
643   // Little-endian dump code_units worth of this instruction, padding to code_units for
644   // shorter instructions
645   std::string DumpHexLE(size_t instr_code_units) const;
646 
Fetch16(size_t offset)647   uint16_t Fetch16(size_t offset) const {
648     const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
649     return insns[offset];
650   }
651 
652  private:
653   size_t SizeInCodeUnitsComplexOpcode() const;
654 
655   // Return how many code unit words are required to compute the size of the opcode.
656   size_t CodeUnitsRequiredForSizeOfComplexOpcode() const;
657 
Fetch32(size_t offset)658   uint32_t Fetch32(size_t offset) const {
659     return (Fetch16(offset) | ((uint32_t) Fetch16(offset + 1) << 16));
660   }
661 
InstA()662   uint4_t InstA() const {
663     return InstA(Fetch16(0));
664   }
665 
InstB()666   uint4_t InstB() const {
667     return InstB(Fetch16(0));
668   }
669 
InstAA()670   uint8_t InstAA() const {
671     return InstAA(Fetch16(0));
672   }
673 
InstA(uint16_t inst_data)674   uint4_t InstA(uint16_t inst_data) const {
675     DCHECK_EQ(inst_data, Fetch16(0));
676     return static_cast<uint4_t>((inst_data >> 8) & 0x0f);
677   }
678 
InstB(uint16_t inst_data)679   uint4_t InstB(uint16_t inst_data) const {
680     DCHECK_EQ(inst_data, Fetch16(0));
681     return static_cast<uint4_t>(inst_data >> 12);
682   }
683 
InstAA(uint16_t inst_data)684   uint8_t InstAA(uint16_t inst_data) const {
685     DCHECK_EQ(inst_data, Fetch16(0));
686     return static_cast<uint8_t>(inst_data >> 8);
687   }
688 
689   static const char* const kInstructionNames[];
690 
691   static const InstructionDescriptor kInstructionDescriptors[];
692 
693   DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
694 };
695 std::ostream& operator<<(std::ostream& os, const Instruction::Code& code);
696 std::ostream& operator<<(std::ostream& os, const Instruction::Format& format);
697 std::ostream& operator<<(std::ostream& os, const Instruction::Flags& flags);
698 std::ostream& operator<<(std::ostream& os, const Instruction::VerifyFlag& vflags);
699 
700 // Base class for accessing instruction operands. Unifies operand
701 // access for instructions that have range and varargs forms
702 // (e.g. invoke-polymoprhic/range and invoke-polymorphic).
703 class InstructionOperands {
704  public:
InstructionOperands(size_t num_operands)705   explicit InstructionOperands(size_t num_operands) : num_operands_(num_operands) {}
~InstructionOperands()706   virtual ~InstructionOperands() {}
707   virtual uint32_t GetOperand(size_t index) const = 0;
GetNumberOfOperands()708   size_t GetNumberOfOperands() const { return num_operands_; }
709 
710  private:
711   const size_t num_operands_;
712 
713   DISALLOW_IMPLICIT_CONSTRUCTORS(InstructionOperands);
714 };
715 
716 // Class for accessing operands for instructions with a range format
717 // (e.g. 3rc and 4rcc).
718 class RangeInstructionOperands final : public InstructionOperands {
719  public:
RangeInstructionOperands(uint32_t first_operand,size_t num_operands)720   RangeInstructionOperands(uint32_t first_operand, size_t num_operands)
721       : InstructionOperands(num_operands), first_operand_(first_operand) {}
~RangeInstructionOperands()722   ~RangeInstructionOperands() {}
723   uint32_t GetOperand(size_t operand_index) const override;
724 
725  private:
726   const uint32_t first_operand_;
727 
728   DISALLOW_IMPLICIT_CONSTRUCTORS(RangeInstructionOperands);
729 };
730 
731 // Class for accessing operands for instructions with a variable
732 // number of arguments format (e.g. 35c and 45cc).
733 class VarArgsInstructionOperands final : public InstructionOperands {
734  public:
VarArgsInstructionOperands(const uint32_t (& operands)[Instruction::kMaxVarArgRegs],size_t num_operands)735   VarArgsInstructionOperands(const uint32_t (&operands)[Instruction::kMaxVarArgRegs],
736                              size_t num_operands)
737       : InstructionOperands(num_operands), operands_(operands) {}
~VarArgsInstructionOperands()738   ~VarArgsInstructionOperands() {}
739   uint32_t GetOperand(size_t operand_index) const override;
740 
741  private:
742   const uint32_t (&operands_)[Instruction::kMaxVarArgRegs];
743 
744   DISALLOW_IMPLICIT_CONSTRUCTORS(VarArgsInstructionOperands);
745 };
746 
747 // Class for accessing operands without the receiver by wrapping an
748 // existing InstructionOperands instance.
749 class NoReceiverInstructionOperands final : public InstructionOperands {
750  public:
NoReceiverInstructionOperands(const InstructionOperands * const inner)751   explicit NoReceiverInstructionOperands(const InstructionOperands* const inner)
752       : InstructionOperands(inner->GetNumberOfOperands() - 1), inner_(inner) {}
~NoReceiverInstructionOperands()753   ~NoReceiverInstructionOperands() {}
754   uint32_t GetOperand(size_t operand_index) const override;
755 
756  private:
757   const InstructionOperands* const inner_;
758 
759   DISALLOW_IMPLICIT_CONSTRUCTORS(NoReceiverInstructionOperands);
760 };
761 
762 }  // namespace art
763 
764 #endif  // ART_LIBDEXFILE_DEX_DEX_INSTRUCTION_H_
765