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