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_RUNTIME_DEX_INSTRUCTION_H_
18#define ART_RUNTIME_DEX_INSTRUCTION_H_
19
20#include "base/logging.h"
21#include "base/macros.h"
22#include "globals.h"
23
24typedef uint8_t uint4_t;
25typedef int8_t int4_t;
26
27namespace art {
28
29class DexFile;
30
31enum {
32  kNumPackedOpcodes = 0x100
33};
34
35class Instruction {
36 public:
37  // NOP-encoded switch-statement signatures.
38  enum Signatures {
39    kPackedSwitchSignature = 0x0100,
40    kSparseSwitchSignature = 0x0200,
41    kArrayDataSignature = 0x0300,
42  };
43
44  struct PACKED(4) PackedSwitchPayload {
45    const uint16_t ident;
46    const uint16_t case_count;
47    const int32_t first_key;
48    const int32_t targets[];
49
50   private:
51    DISALLOW_COPY_AND_ASSIGN(PackedSwitchPayload);
52  };
53
54  struct PACKED(4) SparseSwitchPayload {
55    const uint16_t ident;
56    const uint16_t case_count;
57    const int32_t keys_and_targets[];
58
59   public:
60    const int32_t* GetKeys() const {
61      return keys_and_targets;
62    }
63
64    const int32_t* GetTargets() const {
65      return keys_and_targets + case_count;
66    }
67
68   private:
69    DISALLOW_COPY_AND_ASSIGN(SparseSwitchPayload);
70  };
71
72  struct PACKED(4) ArrayDataPayload {
73    const uint16_t ident;
74    const uint16_t element_width;
75    const uint32_t element_count;
76    const uint8_t data[];
77
78   private:
79    DISALLOW_COPY_AND_ASSIGN(ArrayDataPayload);
80  };
81
82  enum Code {  // private marker to avoid generate-operator-out.py from processing.
83#define INSTRUCTION_ENUM(opcode, cname, p, f, r, i, a, v) cname = opcode,
84#include "dex_instruction_list.h"
85    DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM)
86#undef DEX_INSTRUCTION_LIST
87#undef INSTRUCTION_ENUM
88    RSUB_INT_LIT16 = RSUB_INT,
89  };
90
91  enum Format {
92    k10x,  // op
93    k12x,  // op vA, vB
94    k11n,  // op vA, #+B
95    k11x,  // op vAA
96    k10t,  // op +AA
97    k20t,  // op +AAAA
98    k22x,  // op vAA, vBBBB
99    k21t,  // op vAA, +BBBB
100    k21s,  // op vAA, #+BBBB
101    k21h,  // op vAA, #+BBBB00000[00000000]
102    k21c,  // op vAA, thing@BBBB
103    k23x,  // op vAA, vBB, vCC
104    k22b,  // op vAA, vBB, #+CC
105    k22t,  // op vA, vB, +CCCC
106    k22s,  // op vA, vB, #+CCCC
107    k22c,  // op vA, vB, thing@CCCC
108    k32x,  // op vAAAA, vBBBB
109    k30t,  // op +AAAAAAAA
110    k31t,  // op vAA, +BBBBBBBB
111    k31i,  // op vAA, #+BBBBBBBB
112    k31c,  // op vAA, thing@BBBBBBBB
113    k35c,  // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)
114    k3rc,  // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
115    k51l,  // op vAA, #+BBBBBBBBBBBBBBBB
116  };
117
118  enum Flags {
119    kBranch              = 0x000001,  // conditional or unconditional branch
120    kContinue            = 0x000002,  // flow can continue to next statement
121    kSwitch              = 0x000004,  // switch statement
122    kThrow               = 0x000008,  // could cause an exception to be thrown
123    kReturn              = 0x000010,  // returns, no additional statements
124    kInvoke              = 0x000020,  // a flavor of invoke
125    kUnconditional       = 0x000040,  // unconditional branch
126    kAdd                 = 0x000080,  // addition
127    kSubtract            = 0x000100,  // subtract
128    kMultiply            = 0x000200,  // multiply
129    kDivide              = 0x000400,  // division
130    kRemainder           = 0x000800,  // remainder
131    kAnd                 = 0x001000,  // and
132    kOr                  = 0x002000,  // or
133    kXor                 = 0x004000,  // xor
134    kShl                 = 0x008000,  // shl
135    kShr                 = 0x010000,  // shr
136    kUshr                = 0x020000,  // ushr
137    kCast                = 0x040000,  // cast
138    kStore               = 0x080000,  // store opcode
139    kLoad                = 0x100000,  // load opcode
140    kClobber             = 0x200000,  // clobbers memory in a big way (not just a write)
141    kRegCFieldOrConstant = 0x400000,  // is the third virtual register a field or literal constant (vC)
142    kRegBFieldOrConstant = 0x800000,  // is the second virtual register a field or literal constant (vB)
143  };
144
145  enum VerifyFlag {
146    kVerifyNone               = 0x000000,
147    kVerifyRegA               = 0x000001,
148    kVerifyRegAWide           = 0x000002,
149    kVerifyRegB               = 0x000004,
150    kVerifyRegBField          = 0x000008,
151    kVerifyRegBMethod         = 0x000010,
152    kVerifyRegBNewInstance    = 0x000020,
153    kVerifyRegBString         = 0x000040,
154    kVerifyRegBType           = 0x000080,
155    kVerifyRegBWide           = 0x000100,
156    kVerifyRegC               = 0x000200,
157    kVerifyRegCField          = 0x000400,
158    kVerifyRegCNewArray       = 0x000800,
159    kVerifyRegCType           = 0x001000,
160    kVerifyRegCWide           = 0x002000,
161    kVerifyArrayData          = 0x004000,
162    kVerifyBranchTarget       = 0x008000,
163    kVerifySwitchTargets      = 0x010000,
164    kVerifyVarArg             = 0x020000,
165    kVerifyVarArgNonZero      = 0x040000,
166    kVerifyVarArgRange        = 0x080000,
167    kVerifyVarArgRangeNonZero = 0x100000,
168    kVerifyRuntimeOnly        = 0x200000,
169    kVerifyError              = 0x400000,
170  };
171
172  static constexpr uint32_t kMaxVarArgRegs = 5;
173
174  // Returns the size (in 2 byte code units) of this instruction.
175  size_t SizeInCodeUnits() const {
176    int result = kInstructionSizeInCodeUnits[Opcode()];
177    if (UNLIKELY(result < 0)) {
178      return SizeInCodeUnitsComplexOpcode();
179    } else {
180      return static_cast<size_t>(result);
181    }
182  }
183
184  // Reads an instruction out of the stream at the specified address.
185  static const Instruction* At(const uint16_t* code) {
186    DCHECK(code != nullptr);
187    return reinterpret_cast<const Instruction*>(code);
188  }
189
190  // Reads an instruction out of the stream from the current address plus an offset.
191  const Instruction* RelativeAt(int32_t offset) const WARN_UNUSED {
192    return At(reinterpret_cast<const uint16_t*>(this) + offset);
193  }
194
195  // Returns a pointer to the next instruction in the stream.
196  const Instruction* Next() const {
197    return RelativeAt(SizeInCodeUnits());
198  }
199
200  // Returns a pointer to the instruction after this 1xx instruction in the stream.
201  const Instruction* Next_1xx() const {
202    DCHECK(FormatOf(Opcode()) >= k10x && FormatOf(Opcode()) <= k10t);
203    return RelativeAt(1);
204  }
205
206  // Returns a pointer to the instruction after this 2xx instruction in the stream.
207  const Instruction* Next_2xx() const {
208    DCHECK(FormatOf(Opcode()) >= k20t && FormatOf(Opcode()) <= k22c);
209    return RelativeAt(2);
210  }
211
212  // Returns a pointer to the instruction after this 3xx instruction in the stream.
213  const Instruction* Next_3xx() const {
214    DCHECK(FormatOf(Opcode()) >= k32x && FormatOf(Opcode()) <= k3rc);
215    return RelativeAt(3);
216  }
217
218  // Returns a pointer to the instruction after this 51l instruction in the stream.
219  const Instruction* Next_51l() const {
220    DCHECK(FormatOf(Opcode()) == k51l);
221    return RelativeAt(5);
222  }
223
224  // Returns the name of this instruction's opcode.
225  const char* Name() const {
226    return Instruction::Name(Opcode());
227  }
228
229  // Returns the name of the given opcode.
230  static const char* Name(Code opcode) {
231    return kInstructionNames[opcode];
232  }
233
234  // VRegA
235  bool HasVRegA() const;
236  int32_t VRegA() const;
237
238  int8_t VRegA_10t() const {
239    return VRegA_10t(Fetch16(0));
240  }
241  uint8_t VRegA_10x() const {
242    return VRegA_10x(Fetch16(0));
243  }
244  uint4_t VRegA_11n() const {
245    return VRegA_11n(Fetch16(0));
246  }
247  uint8_t VRegA_11x() const {
248    return VRegA_11x(Fetch16(0));
249  }
250  uint4_t VRegA_12x() const {
251    return VRegA_12x(Fetch16(0));
252  }
253  int16_t VRegA_20t() const;
254  uint8_t VRegA_21c() const {
255    return VRegA_21c(Fetch16(0));
256  }
257  uint8_t VRegA_21h() const {
258    return VRegA_21h(Fetch16(0));
259  }
260  uint8_t VRegA_21s() const {
261    return VRegA_21s(Fetch16(0));
262  }
263  uint8_t VRegA_21t() const {
264    return VRegA_21t(Fetch16(0));
265  }
266  uint8_t VRegA_22b() const {
267    return VRegA_22b(Fetch16(0));
268  }
269  uint4_t VRegA_22c() const {
270    return VRegA_22c(Fetch16(0));
271  }
272  uint4_t VRegA_22s() const {
273    return VRegA_22s(Fetch16(0));
274  }
275  uint4_t VRegA_22t() const {
276    return VRegA_22t(Fetch16(0));
277  }
278  uint8_t VRegA_22x() const {
279    return VRegA_22x(Fetch16(0));
280  }
281  uint8_t VRegA_23x() const {
282    return VRegA_23x(Fetch16(0));
283  }
284  int32_t VRegA_30t() const;
285  uint8_t VRegA_31c() const {
286    return VRegA_31c(Fetch16(0));
287  }
288  uint8_t VRegA_31i() const {
289    return VRegA_31i(Fetch16(0));
290  }
291  uint8_t VRegA_31t() const {
292    return VRegA_31t(Fetch16(0));
293  }
294  uint16_t VRegA_32x() const;
295  uint4_t VRegA_35c() const {
296    return VRegA_35c(Fetch16(0));
297  }
298  uint8_t VRegA_3rc() const {
299    return VRegA_3rc(Fetch16(0));
300  }
301  uint8_t VRegA_51l() const {
302    return VRegA_51l(Fetch16(0));
303  }
304
305  // The following methods return the vA operand for various instruction formats. The "inst_data"
306  // parameter holds the first 16 bits of instruction which the returned value is decoded from.
307  int8_t VRegA_10t(uint16_t inst_data) const;
308  uint8_t VRegA_10x(uint16_t inst_data) const;
309  uint4_t VRegA_11n(uint16_t inst_data) const;
310  uint8_t VRegA_11x(uint16_t inst_data) const;
311  uint4_t VRegA_12x(uint16_t inst_data) const;
312  uint8_t VRegA_21c(uint16_t inst_data) const;
313  uint8_t VRegA_21h(uint16_t inst_data) const;
314  uint8_t VRegA_21s(uint16_t inst_data) const;
315  uint8_t VRegA_21t(uint16_t inst_data) const;
316  uint8_t VRegA_22b(uint16_t inst_data) const;
317  uint4_t VRegA_22c(uint16_t inst_data) const;
318  uint4_t VRegA_22s(uint16_t inst_data) const;
319  uint4_t VRegA_22t(uint16_t inst_data) const;
320  uint8_t VRegA_22x(uint16_t inst_data) const;
321  uint8_t VRegA_23x(uint16_t inst_data) const;
322  uint8_t VRegA_31c(uint16_t inst_data) const;
323  uint8_t VRegA_31i(uint16_t inst_data) const;
324  uint8_t VRegA_31t(uint16_t inst_data) const;
325  uint4_t VRegA_35c(uint16_t inst_data) const;
326  uint8_t VRegA_3rc(uint16_t inst_data) const;
327  uint8_t VRegA_51l(uint16_t inst_data) const;
328
329  // VRegB
330  bool HasVRegB() const;
331  int32_t VRegB() const;
332
333  bool HasWideVRegB() const;
334  uint64_t WideVRegB() const;
335
336  int4_t VRegB_11n() const {
337    return VRegB_11n(Fetch16(0));
338  }
339  uint4_t VRegB_12x() const {
340    return VRegB_12x(Fetch16(0));
341  }
342  uint16_t VRegB_21c() const;
343  uint16_t VRegB_21h() const;
344  int16_t VRegB_21s() const;
345  int16_t VRegB_21t() const;
346  uint8_t VRegB_22b() const;
347  uint4_t VRegB_22c() const {
348    return VRegB_22c(Fetch16(0));
349  }
350  uint4_t VRegB_22s() const {
351    return VRegB_22s(Fetch16(0));
352  }
353  uint4_t VRegB_22t() const {
354    return VRegB_22t(Fetch16(0));
355  }
356  uint16_t VRegB_22x() const;
357  uint8_t VRegB_23x() const;
358  uint32_t VRegB_31c() const;
359  int32_t VRegB_31i() const;
360  int32_t VRegB_31t() const;
361  uint16_t VRegB_32x() const;
362  uint16_t VRegB_35c() const;
363  uint16_t VRegB_3rc() const;
364  uint64_t VRegB_51l() const;  // vB_wide
365
366  // The following methods return the vB operand for all instruction formats where it is encoded in
367  // the first 16 bits of instruction. The "inst_data" parameter holds these 16 bits. The returned
368  // value is decoded from it.
369  int4_t VRegB_11n(uint16_t inst_data) const;
370  uint4_t VRegB_12x(uint16_t inst_data) const;
371  uint4_t VRegB_22c(uint16_t inst_data) const;
372  uint4_t VRegB_22s(uint16_t inst_data) const;
373  uint4_t VRegB_22t(uint16_t inst_data) const;
374
375  // VRegC
376  bool HasVRegC() const;
377  int32_t VRegC() const;
378
379  int8_t VRegC_22b() const;
380  uint16_t VRegC_22c() const;
381  int16_t VRegC_22s() const;
382  int16_t VRegC_22t() const;
383  uint8_t VRegC_23x() const;
384  uint4_t VRegC_35c() const;
385  uint16_t VRegC_3rc() const;
386
387  // Fills the given array with the 'arg' array of the instruction.
388  bool HasVarArgs() const;
389  void GetVarArgs(uint32_t args[kMaxVarArgRegs], uint16_t inst_data) const;
390  void GetVarArgs(uint32_t args[kMaxVarArgRegs]) const {
391    return GetVarArgs(args, Fetch16(0));
392  }
393
394  // Returns the opcode field of the instruction. The given "inst_data" parameter must be the first
395  // 16 bits of instruction.
396  Code Opcode(uint16_t inst_data) const {
397    DCHECK_EQ(inst_data, Fetch16(0));
398    return static_cast<Code>(inst_data & 0xFF);
399  }
400
401  // Returns the opcode field of the instruction from the first 16 bits of instruction.
402  Code Opcode() const {
403    return Opcode(Fetch16(0));
404  }
405
406  void SetOpcode(Code opcode) {
407    DCHECK_LT(static_cast<uint16_t>(opcode), 256u);
408    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
409    insns[0] = (insns[0] & 0xff00) | static_cast<uint16_t>(opcode);
410  }
411
412  void SetVRegA_10x(uint8_t val) {
413    DCHECK(FormatOf(Opcode()) == k10x);
414    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
415    insns[0] = (val << 8) | (insns[0] & 0x00ff);
416  }
417
418  void SetVRegB_3rc(uint16_t val) {
419    DCHECK(FormatOf(Opcode()) == k3rc);
420    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
421    insns[1] = val;
422  }
423
424  void SetVRegB_35c(uint16_t val) {
425    DCHECK(FormatOf(Opcode()) == k35c);
426    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
427    insns[1] = val;
428  }
429
430  void SetVRegC_22c(uint16_t val) {
431    DCHECK(FormatOf(Opcode()) == k22c);
432    uint16_t* insns = reinterpret_cast<uint16_t*>(this);
433    insns[1] = val;
434  }
435
436  // Returns the format of the given opcode.
437  static Format FormatOf(Code opcode) {
438    return kInstructionFormats[opcode];
439  }
440
441  // Returns the flags for the given opcode.
442  static int FlagsOf(Code opcode) {
443    return kInstructionFlags[opcode];
444  }
445
446  // Return the verify flags for the given opcode.
447  static int VerifyFlagsOf(Code opcode) {
448    return kInstructionVerifyFlags[opcode];
449  }
450
451  // Returns true if this instruction is a branch.
452  bool IsBranch() const {
453    return (kInstructionFlags[Opcode()] & kBranch) != 0;
454  }
455
456  // Returns true if this instruction is a unconditional branch.
457  bool IsUnconditional() const {
458    return (kInstructionFlags[Opcode()] & kUnconditional) != 0;
459  }
460
461  // Returns the branch offset if this instruction is a branch.
462  int32_t GetTargetOffset() const;
463
464  // Returns true if the instruction allows control flow to go to the following instruction.
465  bool CanFlowThrough() const;
466
467  // Returns true if this instruction is a switch.
468  bool IsSwitch() const {
469    return (kInstructionFlags[Opcode()] & kSwitch) != 0;
470  }
471
472  // Returns true if this instruction can throw.
473  bool IsThrow() const {
474    return (kInstructionFlags[Opcode()] & kThrow) != 0;
475  }
476
477  // Determine if the instruction is any of 'return' instructions.
478  bool IsReturn() const {
479    return (kInstructionFlags[Opcode()] & kReturn) != 0;
480  }
481
482  // Determine if this instruction ends execution of its basic block.
483  bool IsBasicBlockEnd() const {
484    return IsBranch() || IsReturn() || Opcode() == THROW;
485  }
486
487  // Determine if this instruction is an invoke.
488  bool IsInvoke() const {
489    return (kInstructionFlags[Opcode()] & kInvoke) != 0;
490  }
491
492  int GetVerifyTypeArgumentA() const {
493    return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegA | kVerifyRegAWide));
494  }
495
496  int GetVerifyTypeArgumentB() const {
497    return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegB | kVerifyRegBField |
498        kVerifyRegBMethod | kVerifyRegBNewInstance | kVerifyRegBString | kVerifyRegBType |
499        kVerifyRegBWide));
500  }
501
502  int GetVerifyTypeArgumentC() const {
503    return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegC | kVerifyRegCField |
504        kVerifyRegCNewArray | kVerifyRegCType | kVerifyRegCWide));
505  }
506
507  int GetVerifyExtraFlags() const {
508    return (kInstructionVerifyFlags[Opcode()] & (kVerifyArrayData | kVerifyBranchTarget |
509        kVerifySwitchTargets | kVerifyVarArg | kVerifyVarArgNonZero | kVerifyVarArgRange |
510        kVerifyVarArgRangeNonZero | kVerifyError));
511  }
512
513  bool GetVerifyIsRuntimeOnly() const {
514    return (kInstructionVerifyFlags[Opcode()] & kVerifyRuntimeOnly) != 0;
515  }
516
517  // Get the dex PC of this instruction as a offset in code units from the beginning of insns.
518  uint32_t GetDexPc(const uint16_t* insns) const {
519    return (reinterpret_cast<const uint16_t*>(this) - insns);
520  }
521
522  // Dump decoded version of instruction
523  std::string DumpString(const DexFile*) const;
524
525  // Dump code_units worth of this instruction, padding to code_units for shorter instructions
526  std::string DumpHex(size_t code_units) const;
527
528  // Little-endian dump code_units worth of this instruction, padding to code_units for
529  // shorter instructions
530  std::string DumpHexLE(size_t instr_code_units) const;
531
532  uint16_t Fetch16(size_t offset) const {
533    const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
534    return insns[offset];
535  }
536
537 private:
538  size_t SizeInCodeUnitsComplexOpcode() const;
539
540  uint32_t Fetch32(size_t offset) const {
541    return (Fetch16(offset) | ((uint32_t) Fetch16(offset + 1) << 16));
542  }
543
544  uint4_t InstA() const {
545    return InstA(Fetch16(0));
546  }
547
548  uint4_t InstB() const {
549    return InstB(Fetch16(0));
550  }
551
552  uint8_t InstAA() const {
553    return InstAA(Fetch16(0));
554  }
555
556  uint4_t InstA(uint16_t inst_data) const {
557    DCHECK_EQ(inst_data, Fetch16(0));
558    return static_cast<uint4_t>((inst_data >> 8) & 0x0f);
559  }
560
561  uint4_t InstB(uint16_t inst_data) const {
562    DCHECK_EQ(inst_data, Fetch16(0));
563    return static_cast<uint4_t>(inst_data >> 12);
564  }
565
566  uint8_t InstAA(uint16_t inst_data) const {
567    DCHECK_EQ(inst_data, Fetch16(0));
568    return static_cast<uint8_t>(inst_data >> 8);
569  }
570
571  static const char* const kInstructionNames[];
572  static Format const kInstructionFormats[];
573  static int const kInstructionFlags[];
574  static int const kInstructionVerifyFlags[];
575  static int const kInstructionSizeInCodeUnits[];
576  DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
577};
578std::ostream& operator<<(std::ostream& os, const Instruction::Code& code);
579std::ostream& operator<<(std::ostream& os, const Instruction::Format& format);
580std::ostream& operator<<(std::ostream& os, const Instruction::Flags& flags);
581std::ostream& operator<<(std::ostream& os, const Instruction::VerifyFlag& vflags);
582
583}  // namespace art
584
585#endif  // ART_RUNTIME_DEX_INSTRUCTION_H_
586