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