dex_instruction.cc revision 7934ac288acfb2552bb0b06ec1f61e5820d924a4
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) \ 596f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom ((opcode == NOP) ? -1 : \ 606f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom ((format >= k10x) && (format <= k10t)) ? 1 : \ 616f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom ((format >= k20t) && (format <= k22c)) ? 2 : \ 626f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom ((format >= k32x) && (format <= k3rc)) ? 3 : \ 636f485c62b9cfce3ab71020c646ab9f48d9d29d6dBrian Carlstrom (format == k51l) ? 5 : -1), 64a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#include "dex_instruction_list.h" 65a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers DEX_INSTRUCTION_LIST(INSTRUCTION_SIZE) 66a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#undef DEX_INSTRUCTION_LIST 67a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers#undef INSTRUCTION_SIZE 68a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers}; 69a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers 70ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao/* 71ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * Handy macros for helping decode instructions. 72ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao */ 73ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define FETCH(_offset) (insns[(_offset)]) 74807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz#define FETCH_uint32(_offset) (fetch_uint32_impl((_offset), insns)) 75ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_A(_insn) (((uint16_t)(_insn) >> 8) & 0x0f) 76ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_B(_insn) ((uint16_t)(_insn) >> 12) 77ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao#define INST_AA(_insn) ((_insn) >> 8) 78ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 79807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz/* Helper for FETCH_uint32, above. */ 80807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertzstatic inline uint32_t fetch_uint32_impl(uint32_t offset, const uint16_t* insns) { 81ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return insns[offset] | ((uint32_t) insns[offset+1] << 16); 82ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao} 83ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 848cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea 858cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirleabool Instruction::HasVRegC() const { 868cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea switch (FormatOf(Opcode())) { 878cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k23x: return true; 888cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k35c: return true; 898cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k3rc: return true; 908cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea default: return false; 918cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea } 928cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea} 938cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea 948cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirleabool Instruction::HasVRegB() const { 958cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea switch (FormatOf(Opcode())) { 968cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k12x: return true; 978cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k22b: return true; 988cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k22c: return true; 998cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k22s: return true; 1008cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k22t: return true; 1018cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k22x: return true; 1020e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea case k23x: return true; 1038cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k32x: return true; 1048cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea default: return false; 1058cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea } 1068cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea} 1078cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea 1088cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirleabool Instruction::HasVRegA() const { 1098cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea switch (FormatOf(Opcode())) { 1108cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k11n: return true; 1118cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k11x: return true; 1128cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k12x: return true; 1138cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k21c: return true; 1148cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k21h: return true; 1158cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k21s: return true; 1168cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k21t: return true; 1178cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k22b: return true; 1188cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k22c: return true; 1198cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k22s: return true; 1208cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k22t: return true; 1218cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k22x: return true; 1228cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k23x: return true; 1238cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k31c: return true; 1248cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k31i: return true; 1258cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k31t: return true; 1268cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k32x: return true; 1278cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea case k51l: return true; 1288cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea default: return false; 1298cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea } 1308cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea} 1318cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea 13239f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirleaint32_t Instruction::VRegC() const { 13339f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea switch (FormatOf(Opcode())) { 13439f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k23x: return VRegC_23x(); 13539f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k35c: return VRegC_35c(); 13639f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k3rc: return VRegC_3rc(); 13739f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea default: LOG(FATAL) << "Tried to access vC of instruction " << Name() << 13839f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea " which has no C operand."; 13939f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea } 1408cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea return -1; 14139f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea} 14239f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea 14339f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirleaint32_t Instruction::VRegB() const { 14439f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea switch (FormatOf(Opcode())) { 14539f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k12x: return VRegB_12x(); 14639f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k22b: return VRegB_22b(); 14739f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k22c: return VRegB_22c(); 14839f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k22s: return VRegB_22s(); 14939f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k22t: return VRegB_22t(); 15039f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k22x: return VRegB_22x(); 1510e260a32601fb1178e11837c460807071d489f82Dragos Sbirlea case k23x: return VRegB_23x(); 15239f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k32x: return VRegB_32x(); 15339f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea default: LOG(FATAL) << "Tried to access vB of instruction " << Name() << 15439f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea " which has no B operand."; 15539f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea } 1568cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea return -1; 15739f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea} 15839f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea 159d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirleaint32_t Instruction::VRegA() const { 160d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea switch (FormatOf(Opcode())) { 161d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k11n: return VRegA_11n(); 162d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k11x: return VRegA_11x(); 163d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k12x: return VRegA_12x(); 164d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k21c: return VRegA_21c(); 165d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k21h: return VRegA_21h(); 166d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k21s: return VRegA_21s(); 167d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k21t: return VRegA_21t(); 168d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k22b: return VRegA_22b(); 169d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k22c: return VRegA_22c(); 170d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k22s: return VRegA_22s(); 171d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k22t: return VRegA_22t(); 172d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k22x: return VRegA_22x(); 173d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k23x: return VRegA_23x(); 174d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k31c: return VRegA_31c(); 175d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k31i: return VRegA_31i(); 176d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k31t: return VRegA_31t(); 177d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k32x: return VRegA_32x(); 178d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea case k51l: return VRegA_51l(); 1798cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea default: LOG(FATAL) << "Tried to access vA of instruction " << Name() << 180d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea " which has no A operand."; 181d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea } 1828cc5162f19d64eb6414e7e421cea4413debe671eDragos Sbirlea return -1; 183d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea} 184d25de7a7c5f3c9462654a572e28cca73909520b0Dragos Sbirlea 18539f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirleaint32_t Instruction::GetTargetOffset() const { 18639f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea switch (FormatOf(Opcode())) { 18739f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea // Cases for conditional branches follow. 18839f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k22t: return VRegC_22t(); 18939f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k21t: return VRegB_21t(); 19039f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea // Cases for unconditional branches follow. 19139f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k10t: return VRegA_10t(); 19239f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k20t: return VRegA_20t(); 19339f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea case k30t: return VRegA_30t(); 19439f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea default: LOG(FATAL) << "Tried to access the branch offset of an instruction " << Name() << 19539f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea " which does not have a target operand."; 19639f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea } 19739f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea return 0; 19839f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea} 19939f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea 20039f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirleabool Instruction::CanFlowThrough() const { 20139f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea const uint16_t* insns = reinterpret_cast<const uint16_t*>(this); 20239f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea uint16_t insn = *insns; 20339f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea Code opcode = static_cast<Code>(insn & 0xFF); 20439f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea return FlagsOf(opcode) & Instruction::kContinue; 20539f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea} 20639f992750ac1eb7e51955d3e52bddc32b37c370fDragos Sbirlea 207ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhaovoid Instruction::Decode(uint32_t &vA, uint32_t &vB, uint64_t &vB_wide, uint32_t &vC, uint32_t arg[]) const { 208ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao const uint16_t* insns = reinterpret_cast<const uint16_t*>(this); 209ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao uint16_t insn = *insns; 210a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers Code opcode = static_cast<Code>(insn & 0xFF); 211ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 212a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers switch (FormatOf(opcode)) { 213ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k10x: // op 214ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao /* nothing to do; copy the AA bits out for the verifier */ 215ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 216ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 217ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k12x: // op vA, vB 218ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_A(insn); 219ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = INST_B(insn); 220ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 221ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k11n: // op vA, #+B 222ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_A(insn); 2237934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom vB = (int32_t) (INST_B(insn) << 28) >> 28; // sign extend 4-bit value 224ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 225ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k11x: // op vAA 226ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 227ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 228ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k10t: // op +AA 229ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = (int8_t) INST_AA(insn); // sign-extend 8-bit value 230ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 231ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k20t: // op +AAAA 232ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = (int16_t) FETCH(1); // sign-extend 16-bit value 233ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 234ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k21c: // op vAA, thing@BBBB 235ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k22x: // op vAA, vBBBB 236ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 237ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1); 238ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 239ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k21s: // op vAA, #+BBBB 240ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k21t: // op vAA, +BBBB 241ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 242ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = (int16_t) FETCH(1); // sign-extend 16-bit value 243ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 244ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k21h: // op vAA, #+BBBB0000[00000000] 245ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 246ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao /* 247ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * The value should be treated as right-zero-extended, but we don't 248ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * actually do that here. Among other things, we don't know if it's 249ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * the top bits of a 32- or 64-bit value. 250ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao */ 251ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1); 252ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 253ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k23x: // op vAA, vBB, vCC 254ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 255ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1) & 0xff; 256ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vC = FETCH(1) >> 8; 257ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 258ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k22b: // op vAA, vBB, #+CC 259ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 260ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1) & 0xff; 261ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vC = (int8_t) (FETCH(1) >> 8); // sign-extend 8-bit value 262ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 263ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k22s: // op vA, vB, #+CCCC 264ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k22t: // op vA, vB, +CCCC 265ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_A(insn); 266ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = INST_B(insn); 267ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vC = (int16_t) FETCH(1); // sign-extend 16-bit value 268ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 269ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k22c: // op vA, vB, thing@CCCC 270ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_A(insn); 271ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = INST_B(insn); 272ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vC = FETCH(1); 273ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 274ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k30t: // op +AAAAAAAA 275807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz vA = FETCH_uint32(1); // signed 32-bit value 276ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 277ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k31t: // op vAA, +BBBBBBBB 278ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k31c: // op vAA, string@BBBBBBBB 279ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 280807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz vB = FETCH_uint32(1); // 32-bit value 281ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 282ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k32x: // op vAAAA, vBBBB 283ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = FETCH(1); 284ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(2); 285ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 286ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k31i: // op vAA, #+BBBBBBBB 287ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 288807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz vB = FETCH_uint32(1); // signed 32-bit value 289ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 290ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k35c: // op {vC, vD, vE, vF, vG}, thing@BBBB 291ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao { 292ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao /* 293ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * Note that the fields mentioned in the spec don't appear in 294ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * their "usual" positions here compared to most formats. This 295ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * was done so that the field names for the argument count and 296ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * reference index match between this format and the corresponding 297ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * range formats (3rc and friends). 298ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * 299ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * Bottom line: The argument count is always in vA, and the 300ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * method constant (or equivalent) is always in vB. 301ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao */ 302ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao uint16_t regList; 303ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao int count; 304ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 3057934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom vA = INST_B(insn); // This is labeled A in the spec. 306ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1); 307ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao regList = FETCH(2); 308ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 309ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao count = vA; 310ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 311ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao /* 312ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * Copy the argument registers into the arg[] array, and 313ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * also copy the first argument (if any) into vC. (The 314ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * DecodedInstruction structure doesn't have separate 315ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * fields for {vD, vE, vF, vG}, so there's no need to make 316ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao * copies of those.) Note that cases 5..2 fall through. 317ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao */ 318ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao switch (count) { 319ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case 5: arg[4] = INST_A(insn); 320ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case 4: arg[3] = (regList >> 12) & 0x0f; 321ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case 3: arg[2] = (regList >> 8) & 0x0f; 322ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case 2: arg[1] = (regList >> 4) & 0x0f; 323ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case 1: vC = arg[0] = regList & 0x0f; break; 3247934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom case 0: break; // Valid, but no need to do anything. 325ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao default: 326ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao LOG(ERROR) << "Invalid arg count in 35c (" << count << ")"; 327ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return; 328ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao } 329ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao } 330ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 331ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k3rc: // op {vCCCC .. v(CCCC+AA-1)}, meth@BBBB 332ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 333ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vB = FETCH(1); 334ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vC = FETCH(2); 335ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 336ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao case k51l: // op vAA, #+BBBBBBBBBBBBBBBB 337ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao vA = INST_AA(insn); 338807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz vB_wide = FETCH_uint32(1) | ((uint64_t) FETCH_uint32(3) << 32); 339ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao break; 340ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao default: 341a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers LOG(ERROR) << "Can't decode unexpected format " << FormatOf(opcode) << " (op=" << opcode << ")"; 342ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao return; 343ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao } 344ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao} 345ba5ebb944b7c5c6a1b754b6dd47eed96f39aea29jeffhao 346a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogerssize_t Instruction::SizeInCodeUnitsComplexOpcode() const { 34712eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro const uint16_t* insns = reinterpret_cast<const uint16_t*>(this); 348a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers // Handle special NOP encoded variable length sequences. 349a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers switch (*insns) { 350a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers case kPackedSwitchSignature: 351a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers return (4 + insns[1] * 2); 352a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers case kSparseSwitchSignature: 353a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers return (2 + insns[1] * 4); 354a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers case kArrayDataSignature: { 355a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers uint16_t element_size = insns[1]; 356a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers uint32_t length = insns[2] | (((uint32_t)insns[3]) << 16); 357a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers // The plus 1 is to round up for odd size and width. 358a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers return (4 + (element_size * length + 1) / 2); 359e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro } 360a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers default: 361a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers if ((*insns & 0xFF) == 0) { 362a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers return 1; // NOP. 363a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers } else { 364a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers LOG(FATAL) << "Unreachable: " << DumpString(NULL); 365a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers return 0; 366a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers } 367e4c1ce498f7933b91696caa4a527e6556128a8e2Carl Shapiro } 368d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers} 369d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers 3702c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpHex(size_t code_units) const { 371d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers size_t inst_length = SizeInCodeUnits(); 372d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers if (inst_length > code_units) { 373d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers inst_length = code_units; 374d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 3752c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers std::ostringstream os; 376d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers const uint16_t* insn = reinterpret_cast<const uint16_t*>(this); 377d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers for (size_t i = 0; i < inst_length; i++) { 3782c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers os << StringPrintf("0x%04x", insn[i]) << " "; 379d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 380d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers for (size_t i = inst_length; i < code_units; i++) { 381d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers os << " "; 382d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 3832c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers return os.str(); 384d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers} 385d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers 3862c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogersstd::string Instruction::DumpString(const DexFile* file) const { 3872c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers std::ostringstream os; 38875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz const char* opcode = kInstructionNames[Opcode()]; 389adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes switch (FormatOf(Opcode())) { 390e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes case k10x: os << opcode; break; 39175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k12x: os << StringPrintf("%s v%d, v%d", opcode, VRegA_12x(), VRegB_12x()); break; 39275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k11n: os << StringPrintf("%s v%d, #%+d", opcode, VRegA_11n(), VRegB_11n()); break; 39375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k11x: os << StringPrintf("%s v%d", opcode, VRegA_11x()); break; 39475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k10t: os << StringPrintf("%s %+d", opcode, VRegA_10t()); break; 39575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k20t: os << StringPrintf("%s %+d", opcode, VRegA_20t()); break; 39675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k22x: os << StringPrintf("%s v%d, v%d", opcode, VRegA_22x(), VRegB_22x()); break; 39775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k21t: os << StringPrintf("%s v%d, %+d", opcode, VRegA_21t(), VRegB_21t()); break; 39875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k21s: os << StringPrintf("%s v%d, #%+d", opcode, VRegA_21s(), VRegB_21s()); break; 3991b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes case k21h: { 4001b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes // op vAA, #+BBBB0000[00000000] 40175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz if (Opcode() == CONST_HIGH16) { 40275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t value = VRegB_21h() << 16; 40375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz os << StringPrintf("%s v%d, #int %+d // 0x%x", opcode, VRegA_21h(), value, value); 4041b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes } else { 40575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint64_t value = static_cast<uint64_t>(VRegB_21h()) << 48; 40675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz os << StringPrintf("%s v%d, #long %+lld // 0x%llx", opcode, VRegA_21h(), value, value); 4071b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes } 4081b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes } 4091b3d6ca46d9594dbdec66b11f184e6483b007483Elliott Hughes break; 41090334e5586ada4772229ded6f7acb85de524a704Ian Rogers case k21c: { 41175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz switch (Opcode()) { 41290334e5586ada4772229ded6f7acb85de524a704Ian Rogers case CONST_STRING: 41390334e5586ada4772229ded6f7acb85de524a704Ian Rogers if (file != NULL) { 41475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t string_idx = VRegB_21c(); 41575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz os << StringPrintf("const-string v%d, %s // string@%d", VRegA_21c(), 41675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz PrintableString(file->StringDataByIdx(string_idx)).c_str(), string_idx); 41790334e5586ada4772229ded6f7acb85de524a704Ian Rogers break; 41890334e5586ada4772229ded6f7acb85de524a704Ian Rogers } // else fall-through 41918c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier case CHECK_CAST: 42018c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier case CONST_CLASS: 42190334e5586ada4772229ded6f7acb85de524a704Ian Rogers case NEW_INSTANCE: 42290334e5586ada4772229ded6f7acb85de524a704Ian Rogers if (file != NULL) { 42375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t type_idx = VRegB_21c(); 424b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " << PrettyType(type_idx, *file) 42575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz << " // type@" << type_idx; 42690334e5586ada4772229ded6f7acb85de524a704Ian Rogers break; 42790334e5586ada4772229ded6f7acb85de524a704Ian Rogers } // else fall-through 42890334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SGET: 42990334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SGET_WIDE: 43090334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SGET_OBJECT: 43190334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SGET_BOOLEAN: 43290334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SGET_BYTE: 43390334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SGET_CHAR: 43490334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SGET_SHORT: 43590334e5586ada4772229ded6f7acb85de524a704Ian Rogers if (file != NULL) { 43675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t field_idx = VRegB_21c(); 437b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " << PrettyField(field_idx, *file, true) 43875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz << " // field@" << field_idx; 43990334e5586ada4772229ded6f7acb85de524a704Ian Rogers break; 44090334e5586ada4772229ded6f7acb85de524a704Ian Rogers } // else fall-through 44190334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SPUT: 44290334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SPUT_WIDE: 44390334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SPUT_OBJECT: 44490334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SPUT_BOOLEAN: 44590334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SPUT_BYTE: 44690334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SPUT_CHAR: 44790334e5586ada4772229ded6f7acb85de524a704Ian Rogers case SPUT_SHORT: 44890334e5586ada4772229ded6f7acb85de524a704Ian Rogers if (file != NULL) { 44975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t field_idx = VRegB_21c(); 450b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(VRegA_21c()) << ", " << PrettyField(field_idx, *file, true) 45175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz << " // field@" << field_idx; 45290334e5586ada4772229ded6f7acb85de524a704Ian Rogers break; 45390334e5586ada4772229ded6f7acb85de524a704Ian Rogers } // else fall-through 45490334e5586ada4772229ded6f7acb85de524a704Ian Rogers default: 45575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz os << StringPrintf("%s v%d, thing@%d", opcode, VRegA_21c(), VRegB_21c()); 45690334e5586ada4772229ded6f7acb85de524a704Ian Rogers break; 45790334e5586ada4772229ded6f7acb85de524a704Ian Rogers } 45890334e5586ada4772229ded6f7acb85de524a704Ian Rogers break; 45990334e5586ada4772229ded6f7acb85de524a704Ian Rogers } 46075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k23x: os << StringPrintf("%s v%d, v%d, v%d", opcode, VRegA_23x(), VRegB_23x(), VRegC_23x()); break; 46175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k22b: os << StringPrintf("%s v%d, v%d, #%+d", opcode, VRegA_22b(), VRegB_22b(), VRegC_22b()); break; 46275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k22t: os << StringPrintf("%s v%d, v%d, %+d", opcode, VRegA_22t(), VRegB_22t(), VRegC_22t()); break; 46375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k22s: os << StringPrintf("%s v%d, v%d, #%+d", opcode, VRegA_22s(), VRegB_22s(), VRegC_22s()); break; 46490334e5586ada4772229ded6f7acb85de524a704Ian Rogers case k22c: { 46575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz switch (Opcode()) { 46690334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IGET: 46790334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IGET_WIDE: 46890334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IGET_OBJECT: 46990334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IGET_BOOLEAN: 47090334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IGET_BYTE: 47190334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IGET_CHAR: 47290334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IGET_SHORT: 47390334e5586ada4772229ded6f7acb85de524a704Ian Rogers if (file != NULL) { 47475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t field_idx = VRegC_22c(); 475b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", " 47675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz << PrettyField(field_idx, *file, true) << " // field@" << field_idx; 47790334e5586ada4772229ded6f7acb85de524a704Ian Rogers break; 47890334e5586ada4772229ded6f7acb85de524a704Ian Rogers } // else fall-through 4792d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case IGET_QUICK: 4802d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case IGET_OBJECT_QUICK: 4812d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz if (file != NULL) { 4822d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz uint32_t field_idx = VRegC_22c(); 4832d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", " 4842d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz << "// offset@" << field_idx; 4852d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz break; 4862d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } // else fall-through 48790334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IPUT: 48890334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IPUT_WIDE: 48990334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IPUT_OBJECT: 49090334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IPUT_BOOLEAN: 49190334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IPUT_BYTE: 49290334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IPUT_CHAR: 49390334e5586ada4772229ded6f7acb85de524a704Ian Rogers case IPUT_SHORT: 49490334e5586ada4772229ded6f7acb85de524a704Ian Rogers if (file != NULL) { 49575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t field_idx = VRegC_22c(); 496b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", " 49775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz << PrettyField(field_idx, *file, true) << " // field@" << field_idx; 49890334e5586ada4772229ded6f7acb85de524a704Ian Rogers break; 49990334e5586ada4772229ded6f7acb85de524a704Ian Rogers } // else fall-through 5002d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case IPUT_QUICK: 5012d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case IPUT_OBJECT_QUICK: 5022d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz if (file != NULL) { 5032d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz uint32_t field_idx = VRegC_22c(); 5042d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", " 5052d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz << "// offset@" << field_idx; 5062d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz break; 5072d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } // else fall-through 50890334e5586ada4772229ded6f7acb85de524a704Ian Rogers case INSTANCE_OF: 50990334e5586ada4772229ded6f7acb85de524a704Ian Rogers if (file != NULL) { 51075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t type_idx = VRegC_22c(); 511d4e868a25128e31c92b2779e7d2e15f9afdf4fffDragos Sbirlea os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", " 51275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz << PrettyType(type_idx, *file) << " // type@" << type_idx; 51318c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier break; 51418c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier } 51518c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier case NEW_ARRAY: 51618c24b6e05e7591069f1a2ac9c614b28fc0853acMathieu Chartier if (file != NULL) { 51775b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t type_idx = VRegC_22c(); 518b43cef30fa7171f5b33c5f94853ad8474ed08022Dragos Sbirlea os << opcode << " v" << static_cast<int>(VRegA_22c()) << ", v" << static_cast<int>(VRegB_22c()) << ", " 51975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz << PrettyType(type_idx, *file) << " // type@" << type_idx; 52090334e5586ada4772229ded6f7acb85de524a704Ian Rogers break; 52190334e5586ada4772229ded6f7acb85de524a704Ian Rogers } // else fall-through 52290334e5586ada4772229ded6f7acb85de524a704Ian Rogers default: 52375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz os << StringPrintf("%s v%d, v%d, thing@%d", opcode, VRegA_22c(), VRegB_22c(), VRegC_22c()); 52490334e5586ada4772229ded6f7acb85de524a704Ian Rogers break; 52590334e5586ada4772229ded6f7acb85de524a704Ian Rogers } 52690334e5586ada4772229ded6f7acb85de524a704Ian Rogers break; 52790334e5586ada4772229ded6f7acb85de524a704Ian Rogers } 52875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k32x: os << StringPrintf("%s v%d, v%d", opcode, VRegA_32x(), VRegB_32x()); break; 52975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k30t: os << StringPrintf("%s %+d", opcode, VRegA_30t()); break; 53075b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k31t: os << StringPrintf("%s v%d, %+d", opcode, VRegA_31t(), VRegB_31t()); break; 53175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k31i: os << StringPrintf("%s v%d, #%+d", opcode, VRegA_31i(), VRegB_31i()); break; 53275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k31c: os << StringPrintf("%s v%d, thing@%d", opcode, VRegA_31c(), VRegB_31c()); break; 533d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case k35c: { 53475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t arg[5]; 53575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz GetArgs(arg); 53675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz switch (Opcode()) { 537d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case INVOKE_VIRTUAL: 538d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case INVOKE_SUPER: 539d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case INVOKE_DIRECT: 540d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case INVOKE_STATIC: 541d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers case INVOKE_INTERFACE: 542d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers if (file != NULL) { 543e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes os << opcode << " {"; 54475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t method_idx = VRegB_35c(); 54575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz for (size_t i = 0; i < VRegA_35c(); ++i) { 546e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes if (i != 0) { 547e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes os << ", "; 548e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes } 54975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz os << "v" << arg[i]; 550e3c845cdb5884e770287a5c0c65c8bb64733c388Elliott Hughes } 55175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz os << "}, " << PrettyMethod(method_idx, *file) << " // method@" << method_idx; 552d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers break; 553d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } // else fall-through 5542d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case INVOKE_VIRTUAL_QUICK: 5552d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz if (file != NULL) { 5562d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz os << opcode << " {"; 5572d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz uint32_t method_idx = VRegB_35c(); 5582d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz for (size_t i = 0; i < VRegA_35c(); ++i) { 5592d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz if (i != 0) { 5602d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz os << ", "; 5612d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 5622d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz os << "v" << arg[i]; 5632d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } 5647934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom os << "}, // vtable@" << method_idx; 5652d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz break; 5662d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } // else fall-through 567d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers default: 56875b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz os << opcode << " {v" << arg[0] << ", v" << arg[1] << ", v" << arg[2] 56975b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz << ", v" << arg[3] << ", v" << arg[4] << "}, thing@" << VRegB_35c(); 570d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers break; 571d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 572d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers break; 573d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 5744c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers case k3rc: { 57575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz switch (Opcode()) { 5764c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers case INVOKE_VIRTUAL_RANGE: 5774c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers case INVOKE_SUPER_RANGE: 5784c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers case INVOKE_DIRECT_RANGE: 5794c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers case INVOKE_STATIC_RANGE: 5804c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers case INVOKE_INTERFACE_RANGE: 5814c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers if (file != NULL) { 58275b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz uint32_t method_idx = VRegB_3rc(); 58375b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz os << StringPrintf("%s, {v%d .. v%d}, ", opcode, VRegC_3rc(), (VRegC_3rc() + VRegA_3rc() - 1)) 58475b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz << PrettyMethod(method_idx, *file) << " // method@" << method_idx; 5854c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers break; 5864c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers } // else fall-through 5872d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz case INVOKE_VIRTUAL_RANGE_QUICK: 5882d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz if (file != NULL) { 5892d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz uint32_t method_idx = VRegB_3rc(); 5902d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz os << StringPrintf("%s, {v%d .. v%d}, ", opcode, VRegC_3rc(), (VRegC_3rc() + VRegA_3rc() - 1)) 5912d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz << "// vtable@" << method_idx; 5922d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz break; 5932d6ba5158d7fd459db2870df47300b517dc4d08cSebastien Hertz } // else fall-through 5944c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers default: 59575b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz os << StringPrintf("%s, {v%d .. v%d}, thing@%d", opcode, VRegC_3rc(), 59675b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz (VRegC_3rc() + VRegA_3rc() - 1), VRegB_3rc()); 5974c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers break; 5984c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers } 5994c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers break; 6004c5dd5aa7a2cdbec8c298569c5a84d0ef5357363Ian Rogers } 60175b2a4abea8a608d7aec3e417498b69b31026a74Sebastien Hertz case k51l: os << StringPrintf("%s v%d, #%+lld", opcode, VRegA_51l(), VRegB_51l()); break; 6022c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers default: os << " unknown format (" << DumpHex(5) << ")"; break; 603d81871cbbaa34c649e488f94f61a981db33123e5Ian Rogers } 6042c8a857708fc86a5b555d1eb782b56516f3b1a72Ian Rogers return os.str(); 60512eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro} 60612eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro 607a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogersstd::ostream& operator<<(std::ostream& os, const Instruction::Code& code) { 608a75a01313e801c53145df00bad1842d9f643c0a1Ian Rogers return os << Instruction::Name(code); 609adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes} 610adb8c67f6d87a160d4e3a8afea7cb93f6c14568bElliott Hughes 61112eb78e651f13f2c1f0c2c922048a5a213253adfCarl Shapiro} // namespace art 612