dex_instruction.cc revision e3c845cdb5884e770287a5c0c65c8bb64733c388
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
17578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction.h"
1812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
19d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers#include "dex_file.h"
20d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers#include <iomanip>
21d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
2212eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapironamespace art {
2312eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
24e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroconst char* const Instruction::kInstructionNames[] = {
25ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_NAME(o, c, pname, f, r, i, a, v) pname,
26578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
27e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_NAME)
28e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
29e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_NAME
30e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
31e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
32e4c1ce498f7933b91696caa4a527e6556128a8e2Carl ShapiroInstruction::InstructionFormat const Instruction::kInstructionFormats[] = {
33ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_FORMAT(o, c, p, format, r, i, a, v) format,
34578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
35e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_FORMAT)
36e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
37e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_FORMAT
38e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
39e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
40e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroint const Instruction::kInstructionFlags[] = {
41ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_FLAGS(o, c, p, f, r, i, flags, v) flags,
42578bbdc684db8ed68e9fedbc678669d27fa68b6eBrian Carlstrom#include "dex_instruction_list.h"
43e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  DEX_INSTRUCTION_LIST(INSTRUCTION_FLAGS)
44e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef DEX_INSTRUCTION_LIST
45e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro#undef INSTRUCTION_FLAGS
46e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro};
47e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro
48ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaoint const Instruction::kInstructionVerifyFlags[] = {
49ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INSTRUCTION_VERIFY_FLAGS(o, c, p, f, r, i, a, vflags) vflags,
50ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#include "dex_instruction_list.h"
51ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  DEX_INSTRUCTION_LIST(INSTRUCTION_VERIFY_FLAGS)
52ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#undef DEX_INSTRUCTION_LIST
53ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#undef INSTRUCTION_VERIFY_FLAGS
54ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao};
55ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
56ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao/*
57ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * Handy macros for helping decode instructions.
58ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao */
59ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define FETCH(_offset)      (insns[(_offset)])
60ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define FETCH_u4(_offset)   (fetch_u4_impl((_offset), insns))
61ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_A(_insn)       (((uint16_t)(_insn) >> 8) & 0x0f)
62ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_B(_insn)       ((uint16_t)(_insn) >> 12)
63ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_AA(_insn)      ((_insn) >> 8)
64ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
65ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao/* Helper for FETCH_u4, above. */
66ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaostatic inline uint32_t fetch_u4_impl(uint32_t offset, const uint16_t* insns) {
67ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  return insns[offset] | ((uint32_t) insns[offset+1] << 16);
68ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao}
69ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
70ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaovoid Instruction::Decode(uint32_t &vA, uint32_t &vB, uint64_t &vB_wide, uint32_t &vC, uint32_t arg[]) const {
71ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
72ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  uint16_t insn = *insns;
73ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  int opcode = insn & 0xFF;
74ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
75ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  switch (Format()) {
76ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k10x:       // op
77ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      /* nothing to do; copy the AA bits out for the verifier */
78ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
79ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
80ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k12x:       // op vA, vB
81ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_A(insn);
82ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = INST_B(insn);
83ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
84ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k11n:       // op vA, #+B
85ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_A(insn);
86ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = (int32_t) (INST_B(insn) << 28) >> 28; // sign extend 4-bit value
87ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
88ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k11x:       // op vAA
89ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
90ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
91ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k10t:       // op +AA
92ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = (int8_t) INST_AA(insn);              // sign-extend 8-bit value
93ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
94e0cfb6fef149e4b001d580809b2815eb6e181a09jeffhao    case k20bc:      // op AA, kind@BBBB
95e0cfb6fef149e4b001d580809b2815eb6e181a09jeffhao      break;
96ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k20t:       // op +AAAA
97ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = (int16_t) FETCH(1);                   // sign-extend 16-bit value
98ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
99ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k21c:       // op vAA, thing@BBBB
100ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k22x:       // op vAA, vBBBB
101ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
102ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(1);
103ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
104ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k21s:       // op vAA, #+BBBB
105ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k21t:       // op vAA, +BBBB
106ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
107ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = (int16_t) FETCH(1);                   // sign-extend 16-bit value
108ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
109ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k21h:       // op vAA, #+BBBB0000[00000000]
110ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
111ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      /*
112ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao       * The value should be treated as right-zero-extended, but we don't
113ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao       * actually do that here. Among other things, we don't know if it's
114ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao       * the top bits of a 32- or 64-bit value.
115ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao       */
116ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(1);
117ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
118ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k23x:       // op vAA, vBB, vCC
119ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
120ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(1) & 0xff;
121ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vC = FETCH(1) >> 8;
122ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
123ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k22b:       // op vAA, vBB, #+CC
124ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
125ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(1) & 0xff;
126ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vC = (int8_t) (FETCH(1) >> 8);            // sign-extend 8-bit value
127ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
128ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k22s:       // op vA, vB, #+CCCC
129ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k22t:       // op vA, vB, +CCCC
130ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_A(insn);
131ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = INST_B(insn);
132ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vC = (int16_t) FETCH(1);                   // sign-extend 16-bit value
133ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
134ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k22c:       // op vA, vB, thing@CCCC
135ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_A(insn);
136ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = INST_B(insn);
137ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vC = FETCH(1);
138ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
139ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k30t:       // op +AAAAAAAA
140ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = FETCH_u4(1);                     // signed 32-bit value
141ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
142ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k31t:       // op vAA, +BBBBBBBB
143ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k31c:       // op vAA, string@BBBBBBBB
144ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
145ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH_u4(1);                     // 32-bit value
146ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
147ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k32x:       // op vAAAA, vBBBB
148ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = FETCH(1);
149ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(2);
150ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
151ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k31i:       // op vAA, #+BBBBBBBB
152ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
153ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH_u4(1);                     // signed 32-bit value
154ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
155ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k35c:       // op {vC, vD, vE, vF, vG}, thing@BBBB
156ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      {
157ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        /*
158ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * Note that the fields mentioned in the spec don't appear in
159ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * their "usual" positions here compared to most formats. This
160ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * was done so that the field names for the argument count and
161ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * reference index match between this format and the corresponding
162ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * range formats (3rc and friends).
163ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         *
164ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * Bottom line: The argument count is always in vA, and the
165ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * method constant (or equivalent) is always in vB.
166ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         */
167ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        uint16_t regList;
168ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        int count;
169ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
170ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        vA = INST_B(insn); // This is labeled A in the spec.
171ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        vB = FETCH(1);
172ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        regList = FETCH(2);
173ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
174ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        count = vA;
175ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
176ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        /*
177ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * Copy the argument registers into the arg[] array, and
178ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * also copy the first argument (if any) into vC. (The
179ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * DecodedInstruction structure doesn't have separate
180ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * fields for {vD, vE, vF, vG}, so there's no need to make
181ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         * copies of those.) Note that cases 5..2 fall through.
182ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao         */
183ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        switch (count) {
184ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 5: arg[4] = INST_A(insn);
185ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 4: arg[3] = (regList >> 12) & 0x0f;
186ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 3: arg[2] = (regList >> 8) & 0x0f;
187ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 2: arg[1] = (regList >> 4) & 0x0f;
188ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 1: vC = arg[0] = regList & 0x0f; break;
189ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        case 0: break; // Valid, but no need to do anything.
190ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        default:
191ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao          LOG(ERROR) << "Invalid arg count in 35c (" << count << ")";
192ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao          return;
193ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        }
194ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      }
195ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
196ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k3rc:       // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB
197ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
198ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB = FETCH(1);
199ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vC = FETCH(2);
200ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        break;
201ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    case k51l:       // op vAA, #+BBBBBBBBBBBBBBBB
202ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vA = INST_AA(insn);
203ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      vB_wide = FETCH_u4(1) | ((uint64_t) FETCH_u4(3) << 32);
204ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      break;
205ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    default:
206ba8eee10607a524f43b55a6f33c13924fb16d435Elliott Hughes      LOG(ERROR) << "Can't decode unexpected format " << static_cast<int>(Format()) << " (op=" << opcode << ")";
207ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao      return;
208ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  }
209ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao}
210ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao
211d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogerssize_t Instruction::SizeInCodeUnits() const {
21212eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro  const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
213e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  if (*insns == kPackedSwitchSignature) {
214ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    return (4 + insns[1] * 2);
215e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  } else if (*insns == kSparseSwitchSignature) {
216ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    return (2 + insns[1] * 4);
217e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  } else if (*insns == kArrayDataSignature) {
218e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    uint16_t element_size = insns[1];
219e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    uint32_t length = insns[2] | (((uint32_t)insns[3]) << 16);
220e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    // The plus 1 is to round up for odd size and width.
221ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao    return (4 + (element_size * length + 1) / 2);
222e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  } else {
223e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    switch (Format()) {
224e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k10x:
225e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k12x:
226e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k11n:
227e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k11x:
228e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k10t:
229ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        return 1;
2309fdfc1808f2a3845ee7e890a4e5d22a10f2ee93dIan Rogers      case k20bc:
231e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k20t:
232e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k22x:
233e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k21t:
234e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k21s:
235e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k21h:
236e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k21c:
237e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k23x:
238e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k22b:
239e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k22t:
240e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k22s:
241e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k22c:
242ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        return 2;
243e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k32x:
244e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k30t:
245e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k31t:
246e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k31i:
247e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k31c:
248e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k35c:
249e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k3rc:
250ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        return 3;
251e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      case k51l:
252ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao        return 5;
253e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro      default:
254e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro        LOG(FATAL) << "Unreachable";
255e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro    }
256e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  }
257ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao  return 0;
25812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}
25912eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
260e4c1ce498f7933b91696caa4a527e6556128a8e2Carl ShapiroInstruction::Code Instruction::Opcode() const {
26112eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro  const uint16_t* insns = reinterpret_cast<const uint16_t*>(this);
262e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  int opcode = *insns & 0xFF;
263e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro  return static_cast<Code>(opcode);
26412eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}
26512eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
266e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiroconst Instruction* Instruction::Next() const {
267d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  size_t current_size_in_bytes = SizeInCodeUnits() * sizeof(uint16_t);
26812eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro  const uint8_t* ptr = reinterpret_cast<const uint8_t*>(this);
269d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  return reinterpret_cast<const Instruction*>(ptr + current_size_in_bytes);
270d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers}
271d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
2722c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpHex(size_t code_units) const {
273d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  size_t inst_length = SizeInCodeUnits();
274d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  if (inst_length > code_units) {
275d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    inst_length = code_units;
276d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
2772c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  std::ostringstream os;
278d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  const uint16_t* insn = reinterpret_cast<const uint16_t*>(this);
279d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  for (size_t i = 0; i < inst_length; i++) {
2802c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers    os << StringPrintf("0x%04x", insn[i]) << " ";
281d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
282d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  for (size_t i = inst_length; i < code_units; i++) {
283d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    os << "       ";
284d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
2852c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  return os.str();
286d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers}
287d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers
2882c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpString(const DexFile* file) const {
289d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  DecodedInstruction insn(this);
2902c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  std::ostringstream os;
291d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  const char* opcode = kInstructionNames[insn.opcode_];
292d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  switch (Format()) {
293e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k10x:  os << opcode; break;
294e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k12x:  os << StringPrintf("%s v%d, v%d", opcode, insn.vA_, insn.vB_); break;
295e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k11n:  os << StringPrintf("%s v%d, #%+d", opcode, insn.vA_, insn.vB_); break;
296e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k11x:  os << StringPrintf("%s v%d", opcode, insn.vA_); break;
297e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k10t:  os << StringPrintf("%s %+d", opcode, insn.vA_); break;
298e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k20bc: os << StringPrintf("%s %d, kind@%d", opcode, insn.vA_, insn.vB_); break;
299e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k20t:  os << StringPrintf("%s %+d", opcode, insn.vA_); break;
300e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k22x:  os << StringPrintf("%s v%d, v%d", opcode, insn.vA_, insn.vB_); break;
301e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k21t:  os << StringPrintf("%s v%d, %+d", opcode, insn.vA_, insn.vB_); break;
302e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k21s:  os << StringPrintf("%s v%d, #%+d", opcode, insn.vA_, insn.vB_); break;
303e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k21h:  os << StringPrintf("%s v%d, #%+d00000[00000000]", opcode, insn.vA_, insn.vB_); break;
304e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k21c:  os << StringPrintf("%s v%d, thing@%d", opcode, insn.vA_, insn.vB_); break;
305e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k23x:  os << StringPrintf("%s v%d, v%d, v%d", opcode, insn.vA_, insn.vB_, insn.vC_); break;
306e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k22b:  os << StringPrintf("%s v%d, v%d, #%+d", opcode, insn.vA_, insn.vB_, insn.vC_); break;
307e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k22t:  os << StringPrintf("%s v%d, v%d, %+d", opcode, insn.vA_, insn.vB_, insn.vC_); break;
308e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k22s:  os << StringPrintf("%s v%d, v%d, #%+d", opcode, insn.vA_, insn.vB_, insn.vC_); break;
309e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k22c:  os << StringPrintf("%s v%d, v%d, thing@%d", opcode, insn.vA_, insn.vB_, insn.vC_); break;
310e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k32x:  os << StringPrintf("%s v%d, v%d", opcode, insn.vA_, insn.vB_); break;
311e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k30t:  os << StringPrintf("%s %+d", opcode, insn.vA_); break;
312e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k31t:  os << StringPrintf("%s v%d, %+d", opcode, insn.vA_, insn.vB_); break;
313e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k31i:  os << StringPrintf("%s v%d, #%+d", opcode, insn.vA_, insn.vB_); break;
314e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k31c:  os << StringPrintf("%s v%d, thing@%d", opcode, insn.vA_, insn.vB_); break;
315d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    case k35c: {
316d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers      switch (insn.opcode_) {
317d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_VIRTUAL:
318d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_SUPER:
319d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_DIRECT:
320d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_STATIC:
321d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        case INVOKE_INTERFACE:
322d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          if (file != NULL) {
323d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers            const DexFile::MethodId& meth_id = file->GetMethodId(insn.vB_);
324e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            os << opcode << " {";
325e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            for (size_t i = 0; i < insn.vA_; ++i) {
326e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes              if (i != 0) {
327e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes                os << ", ";
328e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes              }
329e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes              os << "v" << insn.arg_[i];
330e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            }
331e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes            os << "}, "
332e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes               << file->GetMethodDeclaringClassDescriptor(meth_id) << "."
333e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes               << file->GetMethodName(meth_id) << file->GetMethodSignature(meth_id)
334e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes               << " // method@" << insn.vB_;
335d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers            break;
336d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          }  // else fall-through
337d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers        default:
338d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          os << opcode << " {v" << insn.arg_[0] << ", v" << insn.arg_[1] << ", v" << insn.arg_[2]
339d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers                       << ", v" << insn.arg_[3] << ", v" << insn.arg_[4] << "}, thing@" << insn.vB_;
340d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers          break;
341d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers      }
342d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers      break;
343d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers    }
344e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k3rc: os << StringPrintf("%s, {v%d .. v%d}, method@%d", opcode, insn.vC_, (insn.vC_+ insn.vA_ - 1), insn.vB_); break;
345e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes    case k51l: os << StringPrintf("%s v%d, #%+d", opcode, insn.vA_, insn.vB_); break;
3462c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers    default: os << " unknown format (" << DumpHex(5) << ")"; break;
347d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers  }
3482c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers  return os.str();
34912eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}
35012eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro
35112eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro}  // namespace art
352