dex_instruction.cc revision d4e868a25128e31c92b2779e7d2e15f9afdf4fff
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 {
2652c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  std::ostringstream os;
26675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz  const char* opcode = kInstructionNames[Opcode()];
267adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes  switch (FormatOf(Opcode())) {
268e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k10x:  os << opcode; break;
26975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k12x:  os << StringPrintf("%s v%d, v%d", opcode, VRegA_12x(), VRegB_12x()); break;
27075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k11n:  os << StringPrintf("%s v%d, #%+d", opcode, VRegA_11n(), VRegB_11n()); break;
27175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k11x:  os << StringPrintf("%s v%d", opcode, VRegA_11x()); break;
27275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k10t:  os << StringPrintf("%s %+d", opcode, VRegA_10t()); break;
27375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k20t:  os << StringPrintf("%s %+d", opcode, VRegA_20t()); break;
27475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22x:  os << StringPrintf("%s v%d, v%d", opcode, VRegA_22x(), VRegB_22x()); break;
27575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k21t:  os << StringPrintf("%s v%d, %+d", opcode, VRegA_21t(), VRegB_21t()); break;
27675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k21s:  os << StringPrintf("%s v%d, #%+d", opcode, VRegA_21s(), VRegB_21s()); break;
2771b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes    case k21h: {
2781b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        // op vAA, #+BBBB0000[00000000]
27975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz        if (Opcode() == CONST_HIGH16) {
28075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          uint32_t value = VRegB_21h() << 16;
28175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s v%d, #int %+d // 0x%x", opcode, VRegA_21h(), value, value);
2821b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        } else {
28375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          uint64_t value = static_cast<uint64_t>(VRegB_21h()) << 48;
28475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s v%d, #long %+lld // 0x%llx", opcode, VRegA_21h(), value, value);
2851b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes        }
2861b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes      }
2871b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes      break;
28890334e5586ada4772229ded6f7acb85de524a704Ian Rogers    case k21c: {
28975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
29090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case CONST_STRING:
29190334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
29275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t string_idx = VRegB_21c();
29375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << StringPrintf("const-string v%d, %s // string@%d", VRegA_21c(),
29475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz                               PrintableString(file->StringDataByIdx(string_idx)).c_str(), string_idx);
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) {
30175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t type_idx = VRegB_21c();
30275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << opcode << " v" << VRegA_21c() << ", " << PrettyType(type_idx, *file)
30375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << " // type@" << type_idx;
30490334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
30590334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
30690334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET:
30790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_WIDE:
30890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_OBJECT:
30990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_BOOLEAN:
31090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_BYTE:
31190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_CHAR:
31290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SGET_SHORT:
31390334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
31475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegB_21c();
31575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << opcode << "  v" << VRegA_21c() << ", " << PrettyField(field_idx, *file, true)
31675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << " // field@" << field_idx;
31790334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
31890334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
31990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT:
32090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_WIDE:
32190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_OBJECT:
32290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_BOOLEAN:
32390334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_BYTE:
32490334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_CHAR:
32590334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case SPUT_SHORT:
32690334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
32775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegB_21c();
32875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << opcode << " v" << VRegA_21c() << ", " << PrettyField(field_idx, *file, true)
32975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << " // field@" << field_idx;
33090334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
33190334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
33290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        default:
33375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s v%d, thing@%d", opcode, VRegA_21c(), VRegB_21c());
33490334e5586ada4772229ded6f7acb85de524a704Ian Rogers          break;
33590334e5586ada4772229ded6f7acb85de524a704Ian Rogers      }
33690334e5586ada4772229ded6f7acb85de524a704Ian Rogers      break;
33790334e5586ada4772229ded6f7acb85de524a704Ian Rogers    }
33875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k23x:  os << StringPrintf("%s v%d, v%d, v%d", opcode, VRegA_23x(), VRegB_23x(), VRegC_23x()); break;
33975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22b:  os << StringPrintf("%s v%d, v%d, #%+d", opcode, VRegA_22b(), VRegB_22b(), VRegC_22b()); break;
34075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22t:  os << StringPrintf("%s v%d, v%d, %+d", opcode, VRegA_22t(), VRegB_22t(), VRegC_22t()); break;
34175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k22s:  os << StringPrintf("%s v%d, v%d, #%+d", opcode, VRegA_22s(), VRegB_22s(), VRegC_22s()); break;
34290334e5586ada4772229ded6f7acb85de524a704Ian Rogers    case k22c: {
34375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
34490334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET:
34590334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_WIDE:
34690334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_OBJECT:
34790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_BOOLEAN:
34890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_BYTE:
34990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_CHAR:
35090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IGET_SHORT:
35190334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
35275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegC_22c();
35375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << opcode << " v" << VRegA_22c() << ", v" << VRegB_22c() << ", "
35475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyField(field_idx, *file, true) << " // field@" << field_idx;
35590334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
35690334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
35790334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT:
35890334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_WIDE:
35990334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_OBJECT:
36090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_BOOLEAN:
36190334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_BYTE:
36290334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_CHAR:
36390334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case IPUT_SHORT:
36490334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
36575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t field_idx = VRegC_22c();
36675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << opcode << " v" << VRegA_22c() << ", v" << VRegB_22c() << ", "
36775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyField(field_idx, *file, true) << " // field@" << field_idx;
36890334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
36990334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
37090334e5586ada4772229ded6f7acb85de524a704Ian Rogers        case INSTANCE_OF:
37190334e5586ada4772229ded6f7acb85de524a704Ian Rogers          if (file != NULL) {
37275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t type_idx = VRegC_22c();
373d4e868a25128e31c92b2779e7d2e15f9afdf4fffDragos Sbirlea            os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", "
37475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyType(type_idx, *file) << " // type@" << type_idx;
37518c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier            break;
37618c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier          }
37718c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier        case NEW_ARRAY:
37818c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier          if (file != NULL) {
37975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t type_idx = VRegC_22c();
38075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << opcode << " v" << VRegA_22c() << ", v" << VRegB_22c() << ", "
38175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyType(type_idx, *file) << " // type@" << type_idx;
38290334e5586ada4772229ded6f7acb85de524a704Ian Rogers            break;
38390334e5586ada4772229ded6f7acb85de524a704Ian Rogers          }  // else fall-through
38490334e5586ada4772229ded6f7acb85de524a704Ian Rogers        default:
38575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s v%d, v%d, thing@%d", opcode, VRegA_22c(), VRegB_22c(), VRegC_22c());
38690334e5586ada4772229ded6f7acb85de524a704Ian Rogers          break;
38790334e5586ada4772229ded6f7acb85de524a704Ian Rogers      }
38890334e5586ada4772229ded6f7acb85de524a704Ian Rogers      break;
38990334e5586ada4772229ded6f7acb85de524a704Ian Rogers    }
39075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k32x:  os << StringPrintf("%s v%d, v%d", opcode, VRegA_32x(), VRegB_32x()); break;
39175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k30t:  os << StringPrintf("%s %+d", opcode, VRegA_30t()); break;
39275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k31t:  os << StringPrintf("%s v%d, %+d", opcode, VRegA_31t(), VRegB_31t()); break;
39375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k31i:  os << StringPrintf("%s v%d, #%+d", opcode, VRegA_31i(), VRegB_31i()); break;
39475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k31c:  os << StringPrintf("%s v%d, thing@%d", opcode, VRegA_31c(), VRegB_31c()); break;
395d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    case k35c: {
39675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      uint32_t arg[5];
39775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      GetArgs(arg);
39875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
399d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_VIRTUAL:
400d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_SUPER:
401d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_DIRECT:
402d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_STATIC:
403d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_INTERFACE:
404d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          if (file != NULL) {
405e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            os << opcode << " {";
40675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t method_idx = VRegB_35c();
40775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            for (size_t i = 0; i < VRegA_35c(); ++i) {
408e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes              if (i != 0) {
409e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes                os << ", ";
410e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes              }
41175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz              os << "v" << arg[i];
412e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            }
41375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << "}, " << PrettyMethod(method_idx, *file) << " // method@" << method_idx;
414d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers            break;
415d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          }  // else fall-through
416d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        default:
41775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << opcode << " {v" << arg[0] << ", v" << arg[1] << ", v" << arg[2]
41875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz                       << ", v" << arg[3] << ", v" << arg[4] << "}, thing@" << VRegB_35c();
419d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          break;
420d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers      }
421d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers      break;
422d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    }
4234c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers    case k3rc: {
42475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz      switch (Opcode()) {
4254c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_VIRTUAL_RANGE:
4264c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_SUPER_RANGE:
4274c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_DIRECT_RANGE:
4284c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_STATIC_RANGE:
4294c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        case INVOKE_INTERFACE_RANGE:
4304c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers          if (file != NULL) {
43175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            uint32_t method_idx = VRegB_3rc();
43275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz            os << StringPrintf("%s, {v%d .. v%d}, ", opcode, VRegC_3rc(), (VRegC_3rc() + VRegA_3rc() - 1))
43375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz               << PrettyMethod(method_idx, *file) << " // method@" << method_idx;
4344c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers            break;
4354c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers          }  // else fall-through
4364c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers        default:
43775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz          os << StringPrintf("%s, {v%d .. v%d}, thing@%d", opcode, VRegC_3rc(),
43875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz                             (VRegC_3rc() + VRegA_3rc() - 1), VRegB_3rc());
4394c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers          break;
4404c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers      }
4414c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers      break;
4424c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers    }
44375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz    case k51l: os << StringPrintf("%s v%d, #%+lld", opcode, VRegA_51l(), VRegB_51l()); break;
4442c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers    default: os << " unknown format (" << DumpHex(5) << ")"; break;
445d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
4462c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  return os.str();
44712eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}
44812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
449a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogersstd::ostream& operator<<(std::ostream& os, const Instruction::Code& code) {
450a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers  return os << Instruction::Name(code);
451adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes}
452adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes
45312eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}  // namespace art
454