dex_instruction.cc revision 807a25640d4f4de8143b160b3bb8f552ffbf6f4a
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
194f6ad8ab428038129b2d0d6c40b7fd625cca15e1Ian Rogers#include "dex_file-inl.h"
202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "utils.h"
21d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers#include <iomanip>
22d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
2312eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapironamespace art {
2412eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
25e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroconst char* const Instruction::kInstructionNames[] = {
26ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_NAME(o, c, pname, f, r, i, a, v) pname,
27578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
28e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_NAME)
29e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
30e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_NAME
31e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
32e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
33adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott HughesInstruction::Format const Instruction::kInstructionFormats[] = {
34ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_FORMAT(o, c, p, format, r, i, a, v) format,
35578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
36e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_FORMAT)
37e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
38e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_FORMAT
39e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
40e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
41e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroint const Instruction::kInstructionFlags[] = {
42ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_FLAGS(o, c, p, f, r, i, flags, v) flags,
43578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
44e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_FLAGS)
45e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
46e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_FLAGS
47e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
48e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
49ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaoint const Instruction::kInstructionVerifyFlags[] = {
50ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_VERIFY_FLAGS(o, c, p, f, r, i, a, vflags) vflags,
51ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#include "dex_instruction_list.h"
52ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  DEX_INSTRUCTION_LIST(INSTRUCTION_VERIFY_FLAGS)
53ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#undef DEX_INSTRUCTION_LIST
54ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#undef INSTRUCTION_VERIFY_FLAGS
55ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao};
56ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
57a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogersint const Instruction::kInstructionSizeInCodeUnits[] = {
58a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#define INSTRUCTION_SIZE(opcode, c, p, format, r, i, a, v) \
59a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  (( opcode == NOP                      ) ? -1 : \
60a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers   ((format >= k10x) && (format <= k10t)) ? 1 : \
61a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers   ((format >= k20t) && (format <= k22c)) ? 2 : \
62a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers   ((format >= k32x) && (format <= k3rc)) ? 3 : \
63a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers   ( format == k51l                     ) ? 5 : -1 \
64a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  ),
65a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#include "dex_instruction_list.h"
66a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  DEX_INSTRUCTION_LIST(INSTRUCTION_SIZE)
67a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#undef DEX_INSTRUCTION_LIST
68a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#undef INSTRUCTION_SIZE
69a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers};
70a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers
71ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao/*
72ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * Handy macros for helping decode instructions.
73ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao */
74ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define FETCH(_offset)      (insns[(_offset)])
75807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz#define FETCH_uint32(_offset)   (fetch_uint32_impl((_offset), insns))
76ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_A(_insn)       (((uint16_t)(_insn) >> 8) & 0x0f)
77ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_B(_insn)       ((uint16_t)(_insn) >> 12)
78ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_AA(_insn)      ((_insn) >> 8)
79ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
80807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz/* Helper for FETCH_uint32, above. */
81807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertzstatic inline uint32_t fetch_uint32_impl(uint32_t offset, const uint16_t* insns) {
82ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  return insns[offset] | ((uint32_t) insns[offset+1] << 16);
83ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao}
84ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
85ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaovoid Instruction::Decode(uint32_t &vA, uint32_t &vB, uint64_t &vB_wide, uint32_t &vC, uint32_t arg[]) const {
86ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
87ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  uint16_t insn = *insns;
88a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  Code opcode = static_cast<Code>(insn & 0xFF);
89ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
90a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  switch (FormatOf(opcode)) {
91ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k10x:       // op
92ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      /* nothing to do; copy the AA bits out for the verifier */
93ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
94ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
95ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k12x:       // op vA, vB
96ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_A(insn);
97ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = INST_B(insn);
98ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
99ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k11n:       // op vA, #+B
100ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_A(insn);
101ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = (int32_t) (INST_B(insn) << 28) >> 28; // sign extend 4-bit value
102ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
103ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k11x:       // op vAA
104ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
105ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
106ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k10t:       // op +AA
107ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = (int8_t) INST_AA(insn);              // sign-extend 8-bit value
108ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
109ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k20t:       // op +AAAA
110ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = (int16_t) FETCH(1);                   // sign-extend 16-bit value
111ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
112ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k21c:       // op vAA, thing@BBBB
113ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k22x:       // op vAA, vBBBB
114ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
115ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(1);
116ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
117ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k21s:       // op vAA, #+BBBB
118ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k21t:       // op vAA, +BBBB
119ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
120ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = (int16_t) FETCH(1);                   // sign-extend 16-bit value
121ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
122ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k21h:       // op vAA, #+BBBB0000[00000000]
123ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
124ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      /*
125ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao       * The value should be treated as right-zero-extended, but we don't
126ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao       * actually do that here. Among other things, we don't know if it's
127ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao       * the top bits of a 32- or 64-bit value.
128ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao       */
129ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(1);
130ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
131ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k23x:       // op vAA, vBB, vCC
132ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
133ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(1) & 0xff;
134ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vC = FETCH(1) >> 8;
135ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
136ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k22b:       // op vAA, vBB, #+CC
137ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
138ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(1) & 0xff;
139ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vC = (int8_t) (FETCH(1) >> 8);            // sign-extend 8-bit value
140ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
141ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k22s:       // op vA, vB, #+CCCC
142ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k22t:       // op vA, vB, +CCCC
143ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_A(insn);
144ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = INST_B(insn);
145ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vC = (int16_t) FETCH(1);                   // sign-extend 16-bit value
146ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
147ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k22c:       // op vA, vB, thing@CCCC
148ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_A(insn);
149ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = INST_B(insn);
150ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vC = FETCH(1);
151ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
152ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k30t:       // op +AAAAAAAA
153807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz      vA = FETCH_uint32(1);                     // signed 32-bit value
154ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
155ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k31t:       // op vAA, +BBBBBBBB
156ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k31c:       // op vAA, string@BBBBBBBB
157ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
158807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz      vB = FETCH_uint32(1);                     // 32-bit value
159ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
160ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k32x:       // op vAAAA, vBBBB
161ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = FETCH(1);
162ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(2);
163ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
164ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k31i:       // op vAA, #+BBBBBBBB
165ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
166807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz      vB = FETCH_uint32(1);                     // signed 32-bit value
167ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
168ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k35c:       // op {vC, vD, vE, vF, vG}, thing@BBBB
169ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      {
170ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        /*
171ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * Note that the fields mentioned in the spec don't appear in
172ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * their "usual" positions here compared to most formats. This
173ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * was done so that the field names for the argument count and
174ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * reference index match between this format and the corresponding
175ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * range formats (3rc and friends).
176ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         *
177ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * Bottom line: The argument count is always in vA, and the
178ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * method constant (or equivalent) is always in vB.
179ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         */
180ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        uint16_t regList;
181ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        int count;
182ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
183ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        vA = INST_B(insn); // This is labeled A in the spec.
184ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        vB = FETCH(1);
185ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        regList = FETCH(2);
186ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
187ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        count = vA;
188ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
189ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        /*
190ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * Copy the argument registers into the arg[] array, and
191ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * also copy the first argument (if any) into vC. (The
192ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * DecodedInstruction structure doesn't have separate
193ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * fields for {vD, vE, vF, vG}, so there's no need to make
194ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * copies of those.) Note that cases 5..2 fall through.
195ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         */
196ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        switch (count) {
197ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 5: arg[4] = INST_A(insn);
198ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 4: arg[3] = (regList >> 12) & 0x0f;
199ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 3: arg[2] = (regList >> 8) & 0x0f;
200ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 2: arg[1] = (regList >> 4) & 0x0f;
201ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 1: vC = arg[0] = regList & 0x0f; break;
202ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 0: break; // Valid, but no need to do anything.
203ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        default:
204ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao          LOG(ERROR) << "Invalid arg count in 35c (" << count << ")";
205ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao          return;
206ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        }
207ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      }
208ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
209ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k3rc:       // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
210ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
211ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(1);
212ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vC = FETCH(2);
213ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        break;
214ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k51l:       // op vAA, #+BBBBBBBBBBBBBBBB
215ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
216807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz      vB_wide = FETCH_uint32(1) | ((uint64_t) FETCH_uint32(3) << 32);
217ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
218ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    default:
219a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      LOG(ERROR) << "Can't decode unexpected format " << FormatOf(opcode) << " (op=" << opcode << ")";
220ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      return;
221ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  }
222ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao}
223ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
224a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogerssize_t Instruction::SizeInCodeUnitsComplexOpcode() const {
22512eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro  const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
226a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  // Handle special NOP encoded variable length sequences.
227a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  switch (*insns) {
228a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    case kPackedSwitchSignature:
229a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      return (4 + insns[1] * 2);
230a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    case kSparseSwitchSignature:
231a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      return (2 + insns[1] * 4);
232a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    case kArrayDataSignature: {
233a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      uint16_t element_size = insns[1];
234a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      uint32_t length = insns[2] | (((uint32_t)insns[3]) << 16);
235a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      // The plus 1 is to round up for odd size and width.
236a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      return (4 + (element_size * length + 1) / 2);
237e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    }
238a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers    default:
239a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      if ((*insns & 0xFF) == 0) {
240a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        return 1;  // NOP.
241a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      } else {
242a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        LOG(FATAL) << "Unreachable: " << DumpString(NULL);
243a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers        return 0;
244a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers      }
245e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  }
246d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers}
247d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
2482c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpHex(size_t code_units) const {
249d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  size_t inst_length = SizeInCodeUnits();
250d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  if (inst_length > code_units) {
251d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    inst_length = code_units;
252d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
2532c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  std::ostringstream os;
254d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  const uint16_t* insn = reinterpret_cast<const uint16_t*>(this);
255d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  for (size_t i = 0; i < inst_length; i++) {
2562c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers    os << StringPrintf("0x%04x", insn[i]) << " ";
257d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
258d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  for (size_t i = inst_length; i < code_units; i++) {
259d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    os << "       ";
260d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
2612c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  return os.str();
262d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers}
263d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
2642c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpString(const DexFile* file) const {
265d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  DecodedInstruction insn(this);
2662c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  std::ostringstream os;
267adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes  const char* opcode = kInstructionNames[insn.opcode];
268adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes  switch (FormatOf(Opcode())) {
269e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k10x:  os << opcode; break;
270adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k12x:  os << StringPrintf("%s v%d, v%d", opcode, insn.vA, insn.vB); break;
271adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k11n:  os << StringPrintf("%s v%d, #%+d", opcode, insn.vA, insn.vB); break;
272adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k11x:  os << StringPrintf("%s v%d", opcode, insn.vA); break;
273adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k10t:  os << StringPrintf("%s %+d", opcode, insn.vA); break;
274adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k20t:  os << StringPrintf("%s %+d", opcode, insn.vA); break;
275adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k22x:  os << StringPrintf("%s v%d, v%d", opcode, insn.vA, insn.vB); break;
276adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k21t:  os << StringPrintf("%s v%d, %+d", opcode, insn.vA, insn.vB); break;
277adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k21s:  os << StringPrintf("%s v%d, #%+d", opcode, insn.vA, insn.vB); break;
2781b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes    case k21h: {
2791b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        // op vAA, #+BBBB0000[00000000]
2801b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        if (insn.opcode == CONST_HIGH16) {
2811b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes          uint32_t value = insn.vB << 16;
2821b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes          os << StringPrintf("%s v%d, #int %+d // 0x%x", opcode, insn.vA, value, value);
2831b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        } else {
2841b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes          uint64_t value = static_cast<uint64_t>(insn.vB) << 48;
2851b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes          os << StringPrintf("%s v%d, #long %+lld // 0x%llx", opcode, insn.vA, value, value);
2861b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        }
2871b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes      }
2881b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes      break;
28990334e5586ada4772229ded6f7acb85de524a704Ian Rogers    case k21c: {
29090334e5586ada4772229ded6f7acb85de524a704Ian Rogers      switch (insn.opcode) {
29190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case CONST_STRING:
29290334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
2932bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers            os << StringPrintf("const-string v%d, %s // string@%d", insn.vA,
2942bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers                               PrintableString(file->StringDataByIdx(insn.vB)).c_str(), insn.vB);
29590334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
29690334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
29718c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier        case CHECK_CAST:
29818c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier        case CONST_CLASS:
29990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case NEW_INSTANCE:
30090334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
3015a723357e86670fdec8749756dda28105d94c133Ian Rogers            os << opcode << " v" << insn.vA << ", " << PrettyType(insn.vB, *file)
3025a723357e86670fdec8749756dda28105d94c133Ian Rogers               << " // type@" << insn.vB;
30390334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
30490334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
30590334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET:
30690334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_WIDE:
30790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_OBJECT:
30890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_BOOLEAN:
30990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_BYTE:
31090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_CHAR:
31190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_SHORT:
31290334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
3135a723357e86670fdec8749756dda28105d94c133Ian Rogers            os << opcode << "  v" << insn.vA << ", " << PrettyField(insn.vB, *file, true)
3145a723357e86670fdec8749756dda28105d94c133Ian Rogers               << " // field@" << insn.vB;
31590334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
31690334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
31790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT:
31890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_WIDE:
31990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_OBJECT:
32090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_BOOLEAN:
32190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_BYTE:
32290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_CHAR:
32390334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_SHORT:
32490334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
3255a723357e86670fdec8749756dda28105d94c133Ian Rogers            os << opcode << " v" << insn.vA << ", " << PrettyField(insn.vB, *file, true)
3265a723357e86670fdec8749756dda28105d94c133Ian Rogers               << " // field@" << insn.vB;
32790334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
32890334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
32990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        default:
33090334e5586ada4772229ded6f7acb85de524a704Ian Rogers          os << StringPrintf("%s v%d, thing@%d", opcode, insn.vA, insn.vB);
33190334e5586ada4772229ded6f7acb85de524a704Ian Rogers          break;
33290334e5586ada4772229ded6f7acb85de524a704Ian Rogers      }
33390334e5586ada4772229ded6f7acb85de524a704Ian Rogers      break;
33490334e5586ada4772229ded6f7acb85de524a704Ian Rogers    }
335adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k23x:  os << StringPrintf("%s v%d, v%d, v%d", opcode, insn.vA, insn.vB, insn.vC); break;
336adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k22b:  os << StringPrintf("%s v%d, v%d, #%+d", opcode, insn.vA, insn.vB, insn.vC); break;
337adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k22t:  os << StringPrintf("%s v%d, v%d, %+d", opcode, insn.vA, insn.vB, insn.vC); break;
338adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k22s:  os << StringPrintf("%s v%d, v%d, #%+d", opcode, insn.vA, insn.vB, insn.vC); break;
33990334e5586ada4772229ded6f7acb85de524a704Ian Rogers    case k22c: {
34090334e5586ada4772229ded6f7acb85de524a704Ian Rogers      switch (insn.opcode) {
34190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET:
34290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_WIDE:
34390334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_OBJECT:
34490334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_BOOLEAN:
34590334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_BYTE:
34690334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_CHAR:
34790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_SHORT:
34890334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
3495a723357e86670fdec8749756dda28105d94c133Ian Rogers            os << opcode << " v" << insn.vA << ", v" << insn.vB << ", "
3505a723357e86670fdec8749756dda28105d94c133Ian Rogers               << PrettyField(insn.vC, *file, true) << " // field@" << insn.vC;
35190334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
35290334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
35390334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT:
35490334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_WIDE:
35590334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_OBJECT:
35690334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_BOOLEAN:
35790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_BYTE:
35890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_CHAR:
35990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_SHORT:
36090334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
3615a723357e86670fdec8749756dda28105d94c133Ian Rogers            os << opcode << " v" << insn.vA << ", v" << insn.vB << ", "
3625a723357e86670fdec8749756dda28105d94c133Ian Rogers               << PrettyField(insn.vC, *file, true) << " // field@" << insn.vC;
36390334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
36490334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
36590334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case INSTANCE_OF:
36690334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
3675a723357e86670fdec8749756dda28105d94c133Ian Rogers            os << opcode << " v" << insn.vA << ", v" << insn.vB << ", "
3685a723357e86670fdec8749756dda28105d94c133Ian Rogers               << PrettyType(insn.vC, *file) << " // type@" << insn.vC;
36918c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier            break;
37018c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier          }
37118c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier        case NEW_ARRAY:
37218c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier          if (file != NULL) {
3735a723357e86670fdec8749756dda28105d94c133Ian Rogers            os << opcode << " v" << insn.vA << ", v" << insn.vB << ", "
3745a723357e86670fdec8749756dda28105d94c133Ian Rogers               << PrettyType(insn.vC, *file) << " // type@" << insn.vC;
37590334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
37690334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
37790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        default:
37890334e5586ada4772229ded6f7acb85de524a704Ian Rogers          os << StringPrintf("%s v%d, v%d, thing@%d", opcode, insn.vA, insn.vB, insn.vC);
37990334e5586ada4772229ded6f7acb85de524a704Ian Rogers          break;
38090334e5586ada4772229ded6f7acb85de524a704Ian Rogers      }
38190334e5586ada4772229ded6f7acb85de524a704Ian Rogers      break;
38290334e5586ada4772229ded6f7acb85de524a704Ian Rogers    }
383adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k32x:  os << StringPrintf("%s v%d, v%d", opcode, insn.vA, insn.vB); break;
384adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k30t:  os << StringPrintf("%s %+d", opcode, insn.vA); break;
385adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k31t:  os << StringPrintf("%s v%d, %+d", opcode, insn.vA, insn.vB); break;
386adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k31i:  os << StringPrintf("%s v%d, #%+d", opcode, insn.vA, insn.vB); break;
387adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k31c:  os << StringPrintf("%s v%d, thing@%d", opcode, insn.vA, insn.vB); break;
388d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    case k35c: {
389adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes      switch (insn.opcode) {
390d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_VIRTUAL:
391d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_SUPER:
392d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_DIRECT:
393d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_STATIC:
394d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_INTERFACE:
395d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          if (file != NULL) {
396e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            os << opcode << " {";
397adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes            for (size_t i = 0; i < insn.vA; ++i) {
398e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes              if (i != 0) {
399e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes                os << ", ";
400e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes              }
401adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes              os << "v" << insn.arg[i];
402e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            }
4034c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers            os << "}, " << PrettyMethod(insn.vB, *file) << " // method@" << insn.vB;
404d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers            break;
405d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          }  // else fall-through
406d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        default:
407adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes          os << opcode << " {v" << insn.arg[0] << ", v" << insn.arg[1] << ", v" << insn.arg[2]
408adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes                       << ", v" << insn.arg[3] << ", v" << insn.arg[4] << "}, thing@" << insn.vB;
409d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          break;
410d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers      }
411d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers      break;
412d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    }
4134c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers    case k3rc: {
4144c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers      switch (insn.opcode) {
4154c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_VIRTUAL_RANGE:
4164c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_SUPER_RANGE:
4174c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_DIRECT_RANGE:
4184c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_STATIC_RANGE:
4194c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_INTERFACE_RANGE:
4204c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers          if (file != NULL) {
4214c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers            os << StringPrintf("%s, {v%d .. v%d}, ", opcode, insn.vC, (insn.vC + insn.vA - 1))
4224c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers               << PrettyMethod(insn.vB, *file) << " // method@" << insn.vB;
4234c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers            break;
4244c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers          }  // else fall-through
4254c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        default:
4264c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers          os << StringPrintf("%s, {v%d .. v%d}, thing@%d", opcode, insn.vC, (insn.vC + insn.vA - 1),
4274c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers                             insn.vB);
4284c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers          break;
4294c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers      }
4304c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers      break;
4314c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers    }
432adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes    case k51l: os << StringPrintf("%s v%d, #%+d", opcode, insn.vA, insn.vB); break;
4332c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers    default: os << " unknown format (" << DumpHex(5) << ")"; break;
434d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
4352c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  return os.str();
43612eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}
43712eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
438a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogersstd::ostream& operator<<(std::ostream& os, const Instruction::Code& code) {
439a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  return os << Instruction::Name(code);
440adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes}
441adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes
44212eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}  // namespace art
443