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