blob: 8cf645d5bae2abce25fad05d1dba377eeb6f0683 [file] [log] [blame]
Carl Shapiro12eb78e2011-06-24 14:51:06 -07001// Copyright 2011 Google Inc. All Rights Reserved.
2
3#ifndef ART_SRC_DEX_INSTRUCTION_H_
4#define ART_SRC_DEX_INSTRUCTION_H_
5
Brian Carlstrom578bbdc2011-07-21 14:07:47 -07006#include "globals.h"
7#include "logging.h"
8#include "macros.h"
Carl Shapiro12eb78e2011-06-24 14:51:06 -07009
10namespace art {
11
Carl Shapiro12eb78e2011-06-24 14:51:06 -070012class Instruction {
13 public:
Carl Shapiroe4c1ce42011-07-09 02:31:57 -070014 // NOP-encoded switch-statement signatures.
15 enum {
16 kPackedSwitchSignature = 0x0100,
17 kSparseSwitchSignature = 0x0200,
18 kArrayDataSignature = 0x0300
19 };
20
Carl Shapiro12eb78e2011-06-24 14:51:06 -070021 enum Code {
jeffhaoba5ebb92011-08-25 17:24:37 -070022#define INSTRUCTION_ENUM(opcode, cname, p, f, r, i, a, v) cname = opcode,
Brian Carlstrom578bbdc2011-07-21 14:07:47 -070023#include "dex_instruction_list.h"
Carl Shapiro12eb78e2011-06-24 14:51:06 -070024 DEX_INSTRUCTION_LIST(INSTRUCTION_ENUM)
Carl Shapirod84f49c2011-06-29 00:27:46 -070025#undef DEX_INSTRUCTION_LIST
Carl Shapiro12eb78e2011-06-24 14:51:06 -070026#undef INSTRUCTION_ENUM
Carl Shapirod84f49c2011-06-29 00:27:46 -070027 };
Carl Shapiro12eb78e2011-06-24 14:51:06 -070028
Carl Shapiroe4c1ce42011-07-09 02:31:57 -070029 enum InstructionFormat {
30 k10x, // op
31 k12x, // op vA, vB
32 k11n, // op vA, #+B
33 k11x, // op vAA
34 k10t, // op +AA
35 k20t, // op +AAAA
36 k22x, // op vAA, vBBBB
37 k21t, // op vAA, +BBBB
38 k21s, // op vAA, #+BBBB
39 k21h, // op vAA, #+BBBB00000[00000000]
40 k21c, // op vAA, thing@BBBB
41 k23x, // op vAA, vBB, vCC
42 k22b, // op vAA, vBB, #+CC
43 k22t, // op vA, vB, +CCCC
44 k22s, // op vA, vB, #+CCCC
45 k22c, // op vA, vB, thing@CCCC
46 k32x, // op vAAAA, vBBBB
47 k30t, // op +AAAAAAAA
48 k31t, // op vAA, +BBBBBBBB
49 k31i, // op vAA, #+BBBBBBBB
50 k31c, // op vAA, thing@BBBBBBBB
51 k35c, // op {vC, vD, vE, vF, vG}, thing@BBBB (B: count, A: vG)
52 k3rc, // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
53 k51l, // op vAA, #+BBBBBBBBBBBBBBBB
54 };
55
56 enum Flags {
57 kBranch = 0x01, // conditional or unconditional branch
58 kContinue = 0x02, // flow can continue to next statement
59 kSwitch = 0x04, // switch statement
60 kThrow = 0x08, // could cause an exception to be thrown
61 kReturn = 0x10, // returns, no additional statements
62 kInvoke = 0x20, // a flavor of invoke
63 // TODO: kUnconditional
64 };
65
jeffhaoba5ebb92011-08-25 17:24:37 -070066 enum VerifyFlag {
67 kVerifyNone = 0x00000,
68 kVerifyRegA = 0x00001,
69 kVerifyRegAWide = 0x00002,
70 kVerifyRegB = 0x00004,
71 kVerifyRegBField = 0x00008,
72 kVerifyRegBMethod = 0x00010,
73 kVerifyRegBNewInstance = 0x00020,
74 kVerifyRegBString = 0x00040,
75 kVerifyRegBType = 0x00080,
76 kVerifyRegBWide = 0x00100,
77 kVerifyRegC = 0x00200,
78 kVerifyRegCField = 0x00400,
79 kVerifyRegCNewArray = 0x00800,
80 kVerifyRegCType = 0x01000,
81 kVerifyRegCWide = 0x02000,
82 kVerifyArrayData = 0x04000,
83 kVerifyBranchTarget = 0x08000,
84 kVerifySwitchTargets = 0x10000,
85 kVerifyVarArg = 0x20000,
86 kVerifyVarArgRange = 0x40000,
87 kVerifyError = 0x80000,
88 };
89
90 // Decodes this instruction, populating its arguments.
91 void Decode(uint32_t &vA, uint32_t &vB, uint64_t &vB_wide, uint32_t &vC, uint32_t arg[]) const;
92
Carl Shapiro12eb78e2011-06-24 14:51:06 -070093 // Returns the size in bytes of this instruction.
Carl Shapiroe4c1ce42011-07-09 02:31:57 -070094 size_t Size() const;
Carl Shapiro12eb78e2011-06-24 14:51:06 -070095
96 // Returns a pointer to the next instruction in the stream.
Carl Shapiroe4c1ce42011-07-09 02:31:57 -070097 const Instruction* Next() const;
98
99 // Name of the instruction.
100 const char* Name() const {
101 return kInstructionNames[Opcode()];
102 }
Carl Shapiro12eb78e2011-06-24 14:51:06 -0700103
104 // Returns the opcode field of the instruction.
Carl Shapiroe4c1ce42011-07-09 02:31:57 -0700105 Code Opcode() const;
Carl Shapiro12eb78e2011-06-24 14:51:06 -0700106
107 // Reads an instruction out of the stream at the specified address.
jeffhaoba5ebb92011-08-25 17:24:37 -0700108 static const Instruction* At(const byte* code) {
Carl Shapiro12eb78e2011-06-24 14:51:06 -0700109 CHECK(code != NULL);
jeffhaoba5ebb92011-08-25 17:24:37 -0700110 return reinterpret_cast<const Instruction*>(code);
Carl Shapiro12eb78e2011-06-24 14:51:06 -0700111 }
112
Carl Shapiroe4c1ce42011-07-09 02:31:57 -0700113 // Returns the format of the current instruction.
114 InstructionFormat Format() const {
115 return kInstructionFormats[Opcode()];
116 }
117
118 // Returns true if this instruction is a branch.
119 bool IsBranch() const {
120 return (kInstructionFlags[Opcode()] & kBranch) != 0;
121 }
122
jeffhaoba5ebb92011-08-25 17:24:37 -0700123 // Returns true if this instruction is a switch.
124 bool IsSwitch() const {
125 return (kInstructionFlags[Opcode()] & kSwitch) != 0;
126 }
127
128 // Returns true if this instruction can throw.
129 bool IsThrow() const {
130 return (kInstructionFlags[Opcode()] & kThrow) != 0;
131 }
132
Carl Shapiroe4c1ce42011-07-09 02:31:57 -0700133 // Determine if the instruction is any of 'return' instructions.
134 bool IsReturn() const {
135 return (kInstructionFlags[Opcode()] & kReturn) != 0;
136 }
137
138 // Determine if this instruction ends execution of its basic block.
139 bool IsBasicBlockEnd() const {
140 return IsBranch() || IsReturn() || Opcode() == THROW;
141 }
142
143 // Determine if this instruction is an invoke.
144 bool IsInvoke() const {
145 return (kInstructionFlags[Opcode()] & kInvoke) != 0;
146 }
147
jeffhaoba5ebb92011-08-25 17:24:37 -0700148 int GetVerifyTypeArgumentA() const {
149 return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegA | kVerifyRegAWide));
150 }
151
152 int GetVerifyTypeArgumentB() const {
153 return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegB | kVerifyRegBField | kVerifyRegBMethod |
154 kVerifyRegBNewInstance | kVerifyRegBString | kVerifyRegBType | kVerifyRegBWide));
155 }
156
157 int GetVerifyTypeArgumentC() const {
158 return (kInstructionVerifyFlags[Opcode()] & (kVerifyRegC | kVerifyRegCField |
159 kVerifyRegCNewArray | kVerifyRegBType | kVerifyRegBWide));
160 }
161
162 int GetVerifyExtraFlags() const {
163 return (kInstructionVerifyFlags[Opcode()] & (kVerifyArrayData | kVerifyBranchTarget |
164 kVerifySwitchTargets | kVerifyVarArg | kVerifyVarArgRange | kVerifyError));
165 }
166
Carl Shapiro12eb78e2011-06-24 14:51:06 -0700167 private:
Carl Shapiroe4c1ce42011-07-09 02:31:57 -0700168 static const char* const kInstructionNames[];
169 static InstructionFormat const kInstructionFormats[];
170 static int const kInstructionFlags[];
jeffhaoba5ebb92011-08-25 17:24:37 -0700171 static int const kInstructionVerifyFlags[];
Carl Shapiro12eb78e2011-06-24 14:51:06 -0700172 DISALLOW_IMPLICIT_CONSTRUCTORS(Instruction);
173};
174
175} // namespace art
176
177#endif // ART_SRC_DEX_INSTRUCTION_H_