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