dex_instruction.cc revision 29a2648821ea4d0b5d3aecb9f835822fdfe6faa1
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
1612eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
17807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz#include "dex_instruction-inl.h"
1812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
19b574c1816c7a2f160b267cd100f36f157a9abcf6Ian Rogers#include <inttypes.h>
20b574c1816c7a2f160b267cd100f36f157a9abcf6Ian Rogers
21b574c1816c7a2f160b267cd100f36f157a9abcf6Ian Rogers#include <iomanip>
22b574c1816c7a2f160b267cd100f36f157a9abcf6Ian Rogers
234f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "utils.h"
25d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
2612eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapironamespace art {
2712eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
28e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroconst char* const Instruction::kInstructionNames[] = {
29ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_NAME(o, c, pname, f, r, i, a, v) pname,
30578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
31e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_NAME)
32e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
33e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_NAME
34e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
35e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
36adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott HughesInstruction::Format const Instruction::kInstructionFormats[] = {
37ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_FORMAT(o, c, p, format, r, i, a, v) format,
38578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
39e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_FORMAT)
40e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
41e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_FORMAT
42e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
43e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
44e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroint const Instruction::kInstructionFlags[] = {
45ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_FLAGS(o, c, p, f, r, i, flags, v) flags,
46578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
47e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_FLAGS)
48e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
49e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_FLAGS
50e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
51e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
52ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaoint const Instruction::kInstructionVerifyFlags[] = {
53ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_VERIFY_FLAGS(o, c, p, f, r, i, a, vflags) vflags,
54ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#include "dex_instruction_list.h"
55ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  DEX_INSTRUCTION_LIST(INSTRUCTION_VERIFY_FLAGS)
56ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#undef DEX_INSTRUCTION_LIST
57ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#undef INSTRUCTION_VERIFY_FLAGS
58ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao};
59ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
60a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogersint const Instruction::kInstructionSizeInCodeUnits[] = {
61a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#define INSTRUCTION_SIZE(opcode, c, p, format, r, i, a, v) \
626f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom    ((opcode == NOP)                        ? -1 : \
636f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom     ((format >= k10x) && (format <= k10t)) ?  1 : \
646f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom     ((format >= k20t) && (format <= k22c)) ?  2 : \
656f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom     ((format >= k32x) && (format <= k3rc)) ?  3 : \
666f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom      (format == k51l)                      ?  5 : -1),
67a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#include "dex_instruction_list.h"
68a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  DEX_INSTRUCTION_LIST(INSTRUCTION_SIZE)
69a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#undef DEX_INSTRUCTION_LIST
70a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#undef INSTRUCTION_SIZE
71a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers};
72a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers
7339f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirleaint32_t Instruction::GetTargetOffset() const {
7439f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  switch (FormatOf(Opcode())) {
7539f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    // Cases for conditional branches follow.
7639f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    case k22t: return VRegC_22t();
7739f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    case k21t: return VRegB_21t();
7839f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    // Cases for unconditional branches follow.
7939f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    case k10t: return VRegA_10t();
8039f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    case k20t: return VRegA_20t();
8139f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    case k30t: return VRegA_30t();
8239f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    default: LOG(FATAL) << "Tried to access the branch offset of an instruction " << Name() <<
8339f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea        " which does not have a target operand.";
8439f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  }
8539f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  return 0;
8639f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea}
8739f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea
8839f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirleabool Instruction::CanFlowThrough() const {
8939f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
9039f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  uint16_t insn = *insns;
9139f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  Code opcode = static_cast<Code>(insn & 0xFF);
9239f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  return  FlagsOf(opcode) & Instruction::kContinue;
9339f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea}
9439f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea
95a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogerssize_t Instruction::SizeInCodeUnitsComplexOpcode() const {
9612eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro  const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
97a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  // Handle special NOP encoded variable length sequences.
98a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  switch (*insns) {
99a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    case kPackedSwitchSignature:
100a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      return (4 + insns[1] * 2);
101a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    case kSparseSwitchSignature:
102a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      return (2 + insns[1] * 4);
103a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    case kArrayDataSignature: {
104a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      uint16_t element_size = insns[1];
105a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      uint32_t length = insns[2] | (((uint32_t)insns[3]) << 16);
106a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      // The plus 1 is to round up for odd size and width.
107a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      return (4 + (element_size * length + 1) / 2);
108e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    }
109a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    default:
110a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      if ((*insns & 0xFF) == 0) {
111a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        return 1;  // NOP.
112a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      } else {
113a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        LOG(FATAL) << "Unreachable: " << DumpString(NULL);
114a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        return 0;
115a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      }
116e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  }
117d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers}
118d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
1192c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpHex(size_t code_units) const {
120d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  size_t inst_length = SizeInCodeUnits();
121d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  if (inst_length > code_units) {
122d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    inst_length = code_units;
123d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
1242c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  std::ostringstream os;
125d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  const uint16_t* insn = reinterpret_cast<const uint16_t*>(this);
126d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  for (size_t i = 0; i < inst_length; i++) {
1272c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers    os << StringPrintf("0x%04x", insn[i]) << " ";
128d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
129d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  for (size_t i = inst_length; i < code_units; i++) {
130d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    os << "       ";
131d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
1322c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  return os.str();
133d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers}
134d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
1352c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpString(const DexFile* file) const {
1362c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  std::ostringstream os;
13775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz  const char* opcode = kInstructionNames[Opcode()];
138adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes  switch (FormatOf(Opcode())) {
139e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k10x:  os << opcode; break;
14075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k12x:  os << StringPrintf("%s v%d, v%d", opcode, VRegA_12x(), VRegB_12x()); break;
14175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k11n:  os << StringPrintf("%s v%d, #%+d", opcode, VRegA_11n(), VRegB_11n()); break;
14275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k11x:  os << StringPrintf("%s v%d", opcode, VRegA_11x()); break;
14375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k10t:  os << StringPrintf("%s %+d", opcode, VRegA_10t()); break;
14475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k20t:  os << StringPrintf("%s %+d", opcode, VRegA_20t()); break;
14575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22x:  os << StringPrintf("%s v%d, v%d", opcode, VRegA_22x(), VRegB_22x()); break;
14675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k21t:  os << StringPrintf("%s v%d, %+d", opcode, VRegA_21t(), VRegB_21t()); break;
14775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k21s:  os << StringPrintf("%s v%d, #%+d", opcode, VRegA_21s(), VRegB_21s()); break;
1481b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes    case k21h: {
1491b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        // op vAA, #+BBBB0000[00000000]
15075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz        if (Opcode() == CONST_HIGH16) {
15175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          uint32_t value = VRegB_21h() << 16;
15275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s v%d, #int %+d // 0x%x", opcode, VRegA_21h(), value, value);
1531b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        } else {
15475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          uint64_t value = static_cast<uint64_t>(VRegB_21h()) << 48;
155b574c1816c7a2f160b267cd100f36f157a9abcf6Ian Rogers          os << StringPrintf("%s v%d, #long %+" PRId64 " // 0x%" PRIx64, opcode, VRegA_21h(),
156b574c1816c7a2f160b267cd100f36f157a9abcf6Ian Rogers                             value, value);
1571b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        }
1581b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes      }
1591b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes      break;
16090334e5586ada4772229ded6f7acb85de524a704Ian Rogers    case k21c: {
16175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
16290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case CONST_STRING:
16390334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
16475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t string_idx = VRegB_21c();
16575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << StringPrintf("const-string v%d, %s // string@%d", VRegA_21c(),
16675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz                               PrintableString(file->StringDataByIdx(string_idx)).c_str(), string_idx);
16790334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
16890334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
16918c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier        case CHECK_CAST:
17018c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier        case CONST_CLASS:
17190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case NEW_INSTANCE:
17290334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
17375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t type_idx = VRegB_21c();
174b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " << PrettyType(type_idx, *file)
17575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << " // type@" << type_idx;
17690334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
17790334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
17890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET:
17990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_WIDE:
18090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_OBJECT:
18190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_BOOLEAN:
18290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_BYTE:
18390334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_CHAR:
18490334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_SHORT:
18590334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
18675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegB_21c();
187b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << "  v" << static_cast<int>(VRegA_21c()) << ", " << PrettyField(field_idx, *file, true)
18875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << " // field@" << field_idx;
18990334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
19090334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
19190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT:
19290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_WIDE:
19390334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_OBJECT:
19490334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_BOOLEAN:
19590334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_BYTE:
19690334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_CHAR:
19790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_SHORT:
19890334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
19975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegB_21c();
200b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " << PrettyField(field_idx, *file, true)
20175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << " // field@" << field_idx;
20290334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
20390334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
20490334e5586ada4772229ded6f7acb85de524a704Ian Rogers        default:
20575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s v%d, thing@%d", opcode, VRegA_21c(), VRegB_21c());
20690334e5586ada4772229ded6f7acb85de524a704Ian Rogers          break;
20790334e5586ada4772229ded6f7acb85de524a704Ian Rogers      }
20890334e5586ada4772229ded6f7acb85de524a704Ian Rogers      break;
20990334e5586ada4772229ded6f7acb85de524a704Ian Rogers    }
21075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k23x:  os << StringPrintf("%s v%d, v%d, v%d", opcode, VRegA_23x(), VRegB_23x(), VRegC_23x()); break;
21175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22b:  os << StringPrintf("%s v%d, v%d, #%+d", opcode, VRegA_22b(), VRegB_22b(), VRegC_22b()); break;
21275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22t:  os << StringPrintf("%s v%d, v%d, %+d", opcode, VRegA_22t(), VRegB_22t(), VRegC_22t()); break;
21375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22s:  os << StringPrintf("%s v%d, v%d, #%+d", opcode, VRegA_22s(), VRegB_22s(), VRegC_22s()); break;
21490334e5586ada4772229ded6f7acb85de524a704Ian Rogers    case k22c: {
21575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
21690334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET:
21790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_WIDE:
21890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_OBJECT:
21990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_BOOLEAN:
22090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_BYTE:
22190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_CHAR:
22290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_SHORT:
22390334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
22475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegC_22c();
225b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
22675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyField(field_idx, *file, true) << " // field@" << field_idx;
22790334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
22890334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
2292d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case IGET_QUICK:
2302d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case IGET_OBJECT_QUICK:
2312d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz          if (file != NULL) {
2322d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            uint32_t field_idx = VRegC_22c();
2332d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
2342d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz               << "// offset@" << field_idx;
2352d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            break;
2362d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz          }  // else fall-through
23790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT:
23890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_WIDE:
23990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_OBJECT:
24090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_BOOLEAN:
24190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_BYTE:
24290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_CHAR:
24390334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_SHORT:
24490334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
24575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegC_22c();
246b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
24775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyField(field_idx, *file, true) << " // field@" << field_idx;
24890334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
24990334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
2502d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case IPUT_QUICK:
2512d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case IPUT_OBJECT_QUICK:
2522d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz          if (file != NULL) {
2532d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            uint32_t field_idx = VRegC_22c();
2542d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
2552d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz               << "// offset@" << field_idx;
2562d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            break;
2572d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz          }  // else fall-through
25890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case INSTANCE_OF:
25990334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
26075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t type_idx = VRegC_22c();
261d4e868a25128e31c92b2779e7d2e15f9afdf4fffDragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
26275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyType(type_idx, *file) << " // type@" << type_idx;
26318c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier            break;
26418c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier          }
26518c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier        case NEW_ARRAY:
26618c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier          if (file != NULL) {
26775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t type_idx = VRegC_22c();
268b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
26975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyType(type_idx, *file) << " // type@" << type_idx;
27090334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
27190334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
27290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        default:
27375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s v%d, v%d, thing@%d", opcode, VRegA_22c(), VRegB_22c(), VRegC_22c());
27490334e5586ada4772229ded6f7acb85de524a704Ian Rogers          break;
27590334e5586ada4772229ded6f7acb85de524a704Ian Rogers      }
27690334e5586ada4772229ded6f7acb85de524a704Ian Rogers      break;
27790334e5586ada4772229ded6f7acb85de524a704Ian Rogers    }
27875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k32x:  os << StringPrintf("%s v%d, v%d", opcode, VRegA_32x(), VRegB_32x()); break;
27975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k30t:  os << StringPrintf("%s %+d", opcode, VRegA_30t()); break;
28075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k31t:  os << StringPrintf("%s v%d, %+d", opcode, VRegA_31t(), VRegB_31t()); break;
28175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k31i:  os << StringPrintf("%s v%d, #%+d", opcode, VRegA_31i(), VRegB_31i()); break;
2827dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers    case k31c:
2837dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers      if (Opcode() == CONST_STRING_JUMBO) {
2847dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers        uint32_t string_idx = VRegB_31c();
2857dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers        if (file != NULL) {
2867dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers          os << StringPrintf("%s v%d, %s // string@%d", opcode, VRegA_31c(),
2877dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers                             PrintableString(file->StringDataByIdx(string_idx)).c_str(),
2887dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers                             string_idx);
2897dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers        } else {
2907dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers          os << StringPrintf("%s v%d, string@%d", opcode, VRegA_31c(), string_idx);
2917dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers        }
2927dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers      } else {
2937dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers        os << StringPrintf("%s v%d, thing@%d", opcode, VRegA_31c(), VRegB_31c()); break;
2947dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers      }
2957dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers      break;
296d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    case k35c: {
29775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      uint32_t arg[5];
29829a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers      GetVarArgs(arg);
29975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
3007aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe        case FILLED_NEW_ARRAY:
3017aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe        {
3027aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe          const int32_t a = VRegA_35c();
3037aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe          os << opcode << " {";
3047aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe          for (int i = 0; i < a; ++i) {
3057aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe            if (i > 0) {
3067aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe              os << ", ";
3077aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe            }
3087aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe            os << "v" << arg[i];
3097aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe          }
3107aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe          os << "}, type@" << VRegB_35c();
3117aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe        }
3127aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe        break;
3137aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe
314d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_VIRTUAL:
315d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_SUPER:
316d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_DIRECT:
317d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_STATIC:
318d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_INTERFACE:
319d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          if (file != NULL) {
320e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            os << opcode << " {";
32175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t method_idx = VRegB_35c();
32275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            for (size_t i = 0; i < VRegA_35c(); ++i) {
323e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes              if (i != 0) {
324e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes                os << ", ";
325e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes              }
32675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz              os << "v" << arg[i];
327e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            }
32875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << "}, " << PrettyMethod(method_idx, *file) << " // method@" << method_idx;
329d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers            break;
330d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          }  // else fall-through
3312d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case INVOKE_VIRTUAL_QUICK:
3322d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz          if (file != NULL) {
3332d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            os << opcode << " {";
3342d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            uint32_t method_idx = VRegB_35c();
3352d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            for (size_t i = 0; i < VRegA_35c(); ++i) {
3362d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz              if (i != 0) {
3372d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz                os << ", ";
3382d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz              }
3392d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz              os << "v" << arg[i];
3402d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            }
3417934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom            os << "},  // vtable@" << method_idx;
3422d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            break;
3432d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz          }  // else fall-through
344d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        default:
34575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << opcode << " {v" << arg[0] << ", v" << arg[1] << ", v" << arg[2]
34675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz                       << ", v" << arg[3] << ", v" << arg[4] << "}, thing@" << VRegB_35c();
347d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          break;
348d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers      }
349d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers      break;
350d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    }
3514c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers    case k3rc: {
35275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
3534c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_VIRTUAL_RANGE:
3544c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_SUPER_RANGE:
3554c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_DIRECT_RANGE:
3564c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_STATIC_RANGE:
3574c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_INTERFACE_RANGE:
3584c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers          if (file != NULL) {
35975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t method_idx = VRegB_3rc();
36075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << StringPrintf("%s, {v%d .. v%d}, ", opcode, VRegC_3rc(), (VRegC_3rc() + VRegA_3rc() - 1))
36175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyMethod(method_idx, *file) << " // method@" << method_idx;
3624c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers            break;
3634c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers          }  // else fall-through
3642d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case INVOKE_VIRTUAL_RANGE_QUICK:
3652d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz          if (file != NULL) {
3662d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            uint32_t method_idx = VRegB_3rc();
3672d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            os << StringPrintf("%s, {v%d .. v%d}, ", opcode, VRegC_3rc(), (VRegC_3rc() + VRegA_3rc() - 1))
3682d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz               << "// vtable@" << method_idx;
3692d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            break;
3702d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz          }  // else fall-through
3714c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        default:
37275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s, {v%d .. v%d}, thing@%d", opcode, VRegC_3rc(),
37375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz                             (VRegC_3rc() + VRegA_3rc() - 1), VRegB_3rc());
3744c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers          break;
3754c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers      }
3764c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers      break;
3774c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers    }
378b574c1816c7a2f160b267cd100f36f157a9abcf6Ian Rogers    case k51l: os << StringPrintf("%s v%d, #%+" PRId64, opcode, VRegA_51l(), VRegB_51l()); break;
3792c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers    default: os << " unknown format (" << DumpHex(5) << ")"; break;
380d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
3812c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  return os.str();
38212eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}
38312eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
384a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogersstd::ostream& operator<<(std::ostream& os, const Instruction::Code& code) {
385a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  return os << Instruction::Name(code);
386adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes}
387adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes
38812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}  // namespace art
389