dex_instruction.cc revision b43cef30fa7171f5b33c5f94853ad8474ed08022
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(); 302b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(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(); 315b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(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(); 328b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(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(); 353b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(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(); 366b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(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(); 380b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(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