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>
22c7dd295a4e0cc1d15c0c96088e55a85389bade74Ian Rogers#include <sstream>
23b574c1816c7a2f160b267cd100f36f157a9abcf6Ian Rogers
24576ca0cd692c0b6ae70e776de91015b8ff000a08Ian Rogers#include "base/stringprintf.h"
254f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "utils.h"
27d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
2812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapironamespace art {
2912eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
30e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroconst char* const Instruction::kInstructionNames[] = {
31ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_NAME(o, c, pname, f, r, i, a, v) pname,
32578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
33e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_NAME)
34e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
35e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_NAME
36e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
37e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
38adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott HughesInstruction::Format const Instruction::kInstructionFormats[] = {
39ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_FORMAT(o, c, p, format, r, i, a, v) format,
40578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
41e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_FORMAT)
42e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
43e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_FORMAT
44e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
45e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
46b1f3753d890e17b7b0d4e2779e8dfd8aa5bf0e2dAart BikInstruction::IndexType const Instruction::kInstructionIndexTypes[] = {
47b1f3753d890e17b7b0d4e2779e8dfd8aa5bf0e2dAart Bik#define INSTRUCTION_INDEX_TYPE(o, c, p, f, r, index, a, v) index,
48b1f3753d890e17b7b0d4e2779e8dfd8aa5bf0e2dAart Bik#include "dex_instruction_list.h"
49b1f3753d890e17b7b0d4e2779e8dfd8aa5bf0e2dAart Bik  DEX_INSTRUCTION_LIST(INSTRUCTION_INDEX_TYPE)
50b1f3753d890e17b7b0d4e2779e8dfd8aa5bf0e2dAart Bik#undef DEX_INSTRUCTION_LIST
51b1f3753d890e17b7b0d4e2779e8dfd8aa5bf0e2dAart Bik#undef INSTRUCTION_FLAGS
52b1f3753d890e17b7b0d4e2779e8dfd8aa5bf0e2dAart Bik};
53b1f3753d890e17b7b0d4e2779e8dfd8aa5bf0e2dAart Bik
54e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroint const Instruction::kInstructionFlags[] = {
55ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_FLAGS(o, c, p, f, r, i, flags, v) flags,
56578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
57e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_FLAGS)
58e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
59e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_FLAGS
60e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
61e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
62ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaoint const Instruction::kInstructionVerifyFlags[] = {
63ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_VERIFY_FLAGS(o, c, p, f, r, i, a, vflags) vflags,
64ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#include "dex_instruction_list.h"
65ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  DEX_INSTRUCTION_LIST(INSTRUCTION_VERIFY_FLAGS)
66ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#undef DEX_INSTRUCTION_LIST
67ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#undef INSTRUCTION_VERIFY_FLAGS
68ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao};
69ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
70a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogersint const Instruction::kInstructionSizeInCodeUnits[] = {
71a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#define INSTRUCTION_SIZE(opcode, c, p, format, r, i, a, v) \
726f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom    ((opcode == NOP)                        ? -1 : \
736f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom     ((format >= k10x) && (format <= k10t)) ?  1 : \
74158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin     ((format >= k20t) && (format <= k25x)) ?  2 : \
756f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom     ((format >= k32x) && (format <= k3rc)) ?  3 : \
766f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom      (format == k51l)                      ?  5 : -1),
77a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#include "dex_instruction_list.h"
78a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  DEX_INSTRUCTION_LIST(INSTRUCTION_SIZE)
79a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#undef DEX_INSTRUCTION_LIST
80a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#undef INSTRUCTION_SIZE
81a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers};
82a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers
8339f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirleaint32_t Instruction::GetTargetOffset() const {
8439f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  switch (FormatOf(Opcode())) {
8539f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    // Cases for conditional branches follow.
8639f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    case k22t: return VRegC_22t();
8739f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    case k21t: return VRegB_21t();
8839f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    // Cases for unconditional branches follow.
8939f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    case k10t: return VRegA_10t();
9039f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    case k20t: return VRegA_20t();
9139f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    case k30t: return VRegA_30t();
9239f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea    default: LOG(FATAL) << "Tried to access the branch offset of an instruction " << Name() <<
9339f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea        " which does not have a target operand.";
9439f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  }
9539f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  return 0;
9639f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea}
9739f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea
9839f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirleabool Instruction::CanFlowThrough() const {
9939f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
10039f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  uint16_t insn = *insns;
10139f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  Code opcode = static_cast<Code>(insn & 0xFF);
10239f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea  return  FlagsOf(opcode) & Instruction::kContinue;
10339f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea}
10439f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea
105a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogerssize_t Instruction::SizeInCodeUnitsComplexOpcode() const {
10612eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro  const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
107a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  // Handle special NOP encoded variable length sequences.
108a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  switch (*insns) {
109a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    case kPackedSwitchSignature:
110a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      return (4 + insns[1] * 2);
111a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    case kSparseSwitchSignature:
112a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      return (2 + insns[1] * 4);
113a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    case kArrayDataSignature: {
114a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      uint16_t element_size = insns[1];
115a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      uint32_t length = insns[2] | (((uint32_t)insns[3]) << 16);
116a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      // The plus 1 is to round up for odd size and width.
117a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      return (4 + (element_size * length + 1) / 2);
118e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    }
119a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    default:
120a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      if ((*insns & 0xFF) == 0) {
121a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        return 1;  // NOP.
122a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      } else {
123fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers        LOG(FATAL) << "Unreachable: " << DumpString(nullptr);
1242c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers        UNREACHABLE();
125a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      }
126e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  }
127d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers}
128d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
1292c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpHex(size_t code_units) const {
130d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  size_t inst_length = SizeInCodeUnits();
131d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  if (inst_length > code_units) {
132d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    inst_length = code_units;
133d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
1342c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  std::ostringstream os;
135d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  const uint16_t* insn = reinterpret_cast<const uint16_t*>(this);
136d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  for (size_t i = 0; i < inst_length; i++) {
1372c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers    os << StringPrintf("0x%04x", insn[i]) << " ";
138d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
139d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  for (size_t i = inst_length; i < code_units; i++) {
140d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    os << "       ";
141d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
1422c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  return os.str();
143d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers}
144d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
14532f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudisstd::string Instruction::DumpHexLE(size_t instr_code_units) const {
14632f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis  size_t inst_length = SizeInCodeUnits();
14732f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis  if (inst_length > instr_code_units) {
14832f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis    inst_length = instr_code_units;
14932f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis  }
15032f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis  std::ostringstream os;
15132f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis  const uint16_t* insn = reinterpret_cast<const uint16_t*>(this);
15232f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis  for (size_t i = 0; i < inst_length; i++) {
1534f0be4d51f6842ac432ab24c2091b57806837a69Andreas Gampe    os << StringPrintf("%02x%02x", static_cast<uint8_t>(insn[i] & 0x00FF),
1544f0be4d51f6842ac432ab24c2091b57806837a69Andreas Gampe                       static_cast<uint8_t>((insn[i] & 0xFF00) >> 8)) << " ";
15532f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis  }
15632f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis  for (size_t i = inst_length; i < instr_code_units; i++) {
1574f0be4d51f6842ac432ab24c2091b57806837a69Andreas Gampe    os << "     ";
15832f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis  }
15932f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis  return os.str();
16032f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis}
16132f500daa2c04b1efe946c12c90502736e47d5fcAnestis Bechtsoudis
1622c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpString(const DexFile* file) const {
1632c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  std::ostringstream os;
16475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz  const char* opcode = kInstructionNames[Opcode()];
165adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes  switch (FormatOf(Opcode())) {
166e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k10x:  os << opcode; break;
16775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k12x:  os << StringPrintf("%s v%d, v%d", opcode, VRegA_12x(), VRegB_12x()); break;
16875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k11n:  os << StringPrintf("%s v%d, #%+d", opcode, VRegA_11n(), VRegB_11n()); break;
16975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k11x:  os << StringPrintf("%s v%d", opcode, VRegA_11x()); break;
17075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k10t:  os << StringPrintf("%s %+d", opcode, VRegA_10t()); break;
17175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k20t:  os << StringPrintf("%s %+d", opcode, VRegA_20t()); break;
17275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22x:  os << StringPrintf("%s v%d, v%d", opcode, VRegA_22x(), VRegB_22x()); break;
17375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k21t:  os << StringPrintf("%s v%d, %+d", opcode, VRegA_21t(), VRegB_21t()); break;
17475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k21s:  os << StringPrintf("%s v%d, #%+d", opcode, VRegA_21s(), VRegB_21s()); break;
1751b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes    case k21h: {
1761b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        // op vAA, #+BBBB0000[00000000]
17775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz        if (Opcode() == CONST_HIGH16) {
17875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          uint32_t value = VRegB_21h() << 16;
17975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s v%d, #int %+d // 0x%x", opcode, VRegA_21h(), value, value);
1801b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        } else {
18175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          uint64_t value = static_cast<uint64_t>(VRegB_21h()) << 48;
182b574c1816c7a2f160b267cd100f36f157a9abcf6Ian Rogers          os << StringPrintf("%s v%d, #long %+" PRId64 " // 0x%" PRIx64, opcode, VRegA_21h(),
183b574c1816c7a2f160b267cd100f36f157a9abcf6Ian Rogers                             value, value);
1841b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        }
1851b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes      }
1861b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes      break;
18790334e5586ada4772229ded6f7acb85de524a704Ian Rogers    case k21c: {
18875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
18990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case CONST_STRING:
190fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
19175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t string_idx = VRegB_21c();
19267c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y            if (string_idx < file->NumStringIds()) {
19367c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y              os << StringPrintf("const-string v%d, %s // string@%d",
19467c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                                 VRegA_21c(),
19567c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                                 PrintableString(file->StringDataByIdx(string_idx)).c_str(),
19667c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                                 string_idx);
19767c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y            } else {
19867c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y              os << StringPrintf("const-string v%d, <<invalid-string-idx-%d>> // string@%d",
19967c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                                 VRegA_21c(),
20067c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                                 string_idx,
20167c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                                 string_idx);
20267c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y            }
20390334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
204fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
205fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
20618c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier        case CHECK_CAST:
20718c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier        case CONST_CLASS:
20890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case NEW_INSTANCE:
209fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
21075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t type_idx = VRegB_21c();
211b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " << PrettyType(type_idx, *file)
21275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << " // type@" << type_idx;
21390334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
214fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
215fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
21690334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET:
21790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_WIDE:
21890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_OBJECT:
21990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_BOOLEAN:
22090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_BYTE:
22190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_CHAR:
22290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_SHORT:
223fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
22475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegB_21c();
225b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << "  v" << static_cast<int>(VRegA_21c()) << ", " << PrettyField(field_idx, *file, true)
22675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << " // field@" << field_idx;
22790334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
228fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
229fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
23090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT:
23190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_WIDE:
23290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_OBJECT:
23390334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_BOOLEAN:
23490334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_BYTE:
23590334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_CHAR:
23690334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_SHORT:
237fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
23875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegB_21c();
239b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " << PrettyField(field_idx, *file, true)
24075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << " // field@" << field_idx;
24190334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
242fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
243fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
244158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin        case CREATE_LAMBDA:
245158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin          if (file != nullptr) {
246158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin            uint32_t method_idx = VRegB_21c();
247158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin            os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " << PrettyMethod(method_idx, *file, true)
248158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin               << " // method@" << method_idx;
249158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin            break;
250158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin          }
251158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin          FALLTHROUGH_INTENDED;
25290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        default:
25375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s v%d, thing@%d", opcode, VRegA_21c(), VRegB_21c());
25490334e5586ada4772229ded6f7acb85de524a704Ian Rogers          break;
25590334e5586ada4772229ded6f7acb85de524a704Ian Rogers      }
25690334e5586ada4772229ded6f7acb85de524a704Ian Rogers      break;
25790334e5586ada4772229ded6f7acb85de524a704Ian Rogers    }
25875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k23x:  os << StringPrintf("%s v%d, v%d, v%d", opcode, VRegA_23x(), VRegB_23x(), VRegC_23x()); break;
25975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22b:  os << StringPrintf("%s v%d, v%d, #%+d", opcode, VRegA_22b(), VRegB_22b(), VRegC_22b()); break;
26075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22t:  os << StringPrintf("%s v%d, v%d, %+d", opcode, VRegA_22t(), VRegB_22t(), VRegC_22t()); break;
26175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22s:  os << StringPrintf("%s v%d, v%d, #%+d", opcode, VRegA_22s(), VRegB_22s(), VRegC_22s()); break;
26290334e5586ada4772229ded6f7acb85de524a704Ian Rogers    case k22c: {
26375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
26490334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET:
26590334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_WIDE:
26690334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_OBJECT:
26790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_BOOLEAN:
26890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_BYTE:
26990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_CHAR:
27090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_SHORT:
271fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
27275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegC_22c();
273b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
27475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyField(field_idx, *file, true) << " // field@" << field_idx;
27590334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
276fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
277fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
2782d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case IGET_QUICK:
2792d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case IGET_OBJECT_QUICK:
280fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
2812d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            uint32_t field_idx = VRegC_22c();
2822d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
2832d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz               << "// offset@" << field_idx;
2842d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            break;
285fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
286fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
28790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT:
28890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_WIDE:
28990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_OBJECT:
29090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_BOOLEAN:
29190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_BYTE:
29290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_CHAR:
29390334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_SHORT:
294fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
29575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegC_22c();
296b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
29775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyField(field_idx, *file, true) << " // field@" << field_idx;
29890334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
299fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
300fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
3012d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case IPUT_QUICK:
3022d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case IPUT_OBJECT_QUICK:
303fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
3042d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            uint32_t field_idx = VRegC_22c();
3052d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
3062d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz               << "// offset@" << field_idx;
3072d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            break;
308fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
309fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
31090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case INSTANCE_OF:
311fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
31275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t type_idx = VRegC_22c();
313d4e868a25128e31c92b2779e7d2e15f9afdf4fffDragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
31475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyType(type_idx, *file) << " // type@" << type_idx;
31518c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier            break;
31618c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier          }
317fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
31818c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier        case NEW_ARRAY:
319fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
32075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t type_idx = VRegC_22c();
321b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
32275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyType(type_idx, *file) << " // type@" << type_idx;
32390334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
324fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
325fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
32690334e5586ada4772229ded6f7acb85de524a704Ian Rogers        default:
32775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s v%d, v%d, thing@%d", opcode, VRegA_22c(), VRegB_22c(), VRegC_22c());
32890334e5586ada4772229ded6f7acb85de524a704Ian Rogers          break;
32990334e5586ada4772229ded6f7acb85de524a704Ian Rogers      }
33090334e5586ada4772229ded6f7acb85de524a704Ian Rogers      break;
33190334e5586ada4772229ded6f7acb85de524a704Ian Rogers    }
332158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin    case k25x: {
333158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin      if (Opcode() == INVOKE_LAMBDA) {
3346918bf13eb855b3aa8ccdddda2d27ae8c60cec56Igor Murashkin        uint32_t arg[kMaxVarArgRegs25x];
335158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin        GetAllArgs25x(arg);
336158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin        const size_t num_extra_var_args = VRegB_25x();
3376918bf13eb855b3aa8ccdddda2d27ae8c60cec56Igor Murashkin        DCHECK_LE(num_extra_var_args + 2, arraysize(arg));
338158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin
339158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin        // invoke-lambda vC, {vD, vE, vF, vG}
340158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin        os << opcode << " v" << arg[0] << ", {";
341158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin        for (size_t i = 0; i < num_extra_var_args; ++i) {
342158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin          if (i != 0) {
343158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin            os << ", ";
344158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin          }
34530c475a2046951a81769c2db0b2dad66cd71e189Igor Murashkin          os << "v" << arg[i + 2];  // Don't print the pair of vC registers. Pair is implicit.
346158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin        }
347158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin        os << "}";
348158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin        break;
349158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin      }
350158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin      FALLTHROUGH_INTENDED;
351158f35c98e2ec0d40d2c032b8cdce5fb60944a7fIgor Murashkin    }
35275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k32x:  os << StringPrintf("%s v%d, v%d", opcode, VRegA_32x(), VRegB_32x()); break;
35375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k30t:  os << StringPrintf("%s %+d", opcode, VRegA_30t()); break;
35475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k31t:  os << StringPrintf("%s v%d, %+d", opcode, VRegA_31t(), VRegB_31t()); break;
35575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k31i:  os << StringPrintf("%s v%d, #%+d", opcode, VRegA_31i(), VRegB_31i()); break;
3567dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers    case k31c:
3577dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers      if (Opcode() == CONST_STRING_JUMBO) {
3587dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers        uint32_t string_idx = VRegB_31c();
359fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers        if (file != nullptr) {
36067c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y          if (string_idx < file->NumStringIds()) {
36167c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y            os << StringPrintf("%s v%d, %s // string@%d",
36267c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                               opcode,
36367c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                               VRegA_31c(),
36467c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                               PrintableString(file->StringDataByIdx(string_idx)).c_str(),
36567c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                               string_idx);
36667c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y          } else {
36767c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y            os << StringPrintf("%s v%d, <<invalid-string-idx-%d>> // string@%d",
36867c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                               opcode,
36967c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                               VRegA_31c(),
37067c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                               string_idx,
37167c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y                               string_idx);
37267c5ddd09c404e14d6081d8d918baa2c08b49741Serdjuk, Nikolay Y          }
3737dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers        } else {
3747dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers          os << StringPrintf("%s v%d, string@%d", opcode, VRegA_31c(), string_idx);
3757dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers        }
3767dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers      } else {
3777dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers        os << StringPrintf("%s v%d, thing@%d", opcode, VRegA_31c(), VRegB_31c()); break;
3787dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers      }
3797dfb28c066159e6cde8181720f0c451a700ef966Ian Rogers      break;
380d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    case k35c: {
38175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      uint32_t arg[5];
38229a2648821ea4d0b5d3aecb9f835822fdfe6faa1Ian Rogers      GetVarArgs(arg);
38375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
3847aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe        case FILLED_NEW_ARRAY:
3857aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe        {
3867aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe          const int32_t a = VRegA_35c();
3877aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe          os << opcode << " {";
3887aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe          for (int i = 0; i < a; ++i) {
3897aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe            if (i > 0) {
3907aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe              os << ", ";
3917aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe            }
3927aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe            os << "v" << arg[i];
3937aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe          }
3947aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe          os << "}, type@" << VRegB_35c();
3957aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe        }
3967aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe        break;
3977aca91db1571594cdb7e0a9ee704530b09c066e4Andreas Gampe
398d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_VIRTUAL:
399d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_SUPER:
400d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_DIRECT:
401d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_STATIC:
402d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_INTERFACE:
403fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
404e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            os << opcode << " {";
40575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t method_idx = VRegB_35c();
40675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            for (size_t i = 0; i < VRegA_35c(); ++i) {
407e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes              if (i != 0) {
408e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes                os << ", ";
409e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes              }
41075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz              os << "v" << arg[i];
411e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            }
41275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << "}, " << PrettyMethod(method_idx, *file) << " // method@" << method_idx;
413d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers            break;
414fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
415fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
4162d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case INVOKE_VIRTUAL_QUICK:
417fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
4182d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            os << opcode << " {";
4192d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            uint32_t method_idx = VRegB_35c();
4202d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            for (size_t i = 0; i < VRegA_35c(); ++i) {
4212d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz              if (i != 0) {
4222d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz                os << ", ";
4232d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz              }
4242d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz              os << "v" << arg[i];
4252d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            }
4267934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom            os << "},  // vtable@" << method_idx;
4272d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            break;
428fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
429fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
430d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        default:
43175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << opcode << " {v" << arg[0] << ", v" << arg[1] << ", v" << arg[2]
43275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz                       << ", v" << arg[3] << ", v" << arg[4] << "}, thing@" << VRegB_35c();
433d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          break;
434d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers      }
435d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers      break;
436d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    }
4374c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers    case k3rc: {
43875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
4394c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_VIRTUAL_RANGE:
4404c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_SUPER_RANGE:
4414c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_DIRECT_RANGE:
4424c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_STATIC_RANGE:
4434c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_INTERFACE_RANGE:
444fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
44575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t method_idx = VRegB_3rc();
44675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << StringPrintf("%s, {v%d .. v%d}, ", opcode, VRegC_3rc(), (VRegC_3rc() + VRegA_3rc() - 1))
44775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyMethod(method_idx, *file) << " // method@" << method_idx;
4484c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers            break;
449fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
450fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
4512d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz        case INVOKE_VIRTUAL_RANGE_QUICK:
452fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          if (file != nullptr) {
4532d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            uint32_t method_idx = VRegB_3rc();
4542d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            os << StringPrintf("%s, {v%d .. v%d}, ", opcode, VRegC_3rc(), (VRegC_3rc() + VRegA_3rc() - 1))
4552d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz               << "// vtable@" << method_idx;
4562d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz            break;
457fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          }
458fc787ecd91127b2c8458afd94e5148e2ae51a1f5Ian Rogers          FALLTHROUGH_INTENDED;
4594c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        default:
46075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s, {v%d .. v%d}, thing@%d", opcode, VRegC_3rc(),
46175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz                             (VRegC_3rc() + VRegA_3rc() - 1), VRegB_3rc());
4624c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers          break;
4634c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers      }
4644c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers      break;
4654c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers    }
466b574c1816c7a2f160b267cd100f36f157a9abcf6Ian Rogers    case k51l: os << StringPrintf("%s v%d, #%+" PRId64, opcode, VRegA_51l(), VRegB_51l()); break;
4672c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers    default: os << " unknown format (" << DumpHex(5) << ")"; break;
468d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
4692c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  return os.str();
47012eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}
47112eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
472a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogersstd::ostream& operator<<(std::ostream& os, const Instruction::Code& code) {
473a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  return os << Instruction::Name(code);
474adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes}
475adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes
47612eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}  // namespace art
477