ArchUtility.cpp revision cec26f6ae3347d5ab3d60de02caca2e47151c6b2
1ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* 2ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Copyright (C) 2009 The Android Open Source Project 3ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * 4ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 5ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * you may not use this file except in compliance with the License. 6ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * You may obtain a copy of the License at 7ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * 8ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * http://www.apache.org/licenses/LICENSE-2.0 9ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * 10ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Unless required by applicable law or agreed to in writing, software 11ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * distributed under the License is distributed on an "AS IS" BASIS, 12ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * See the License for the specific language governing permissions and 14ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * limitations under the License. 15ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */ 16ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 17ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#include "../../CompilerInternals.h" 18ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng#include "dexdump/OpCodeNames.h" 1989efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee#include "ArmLIR.h" 20ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 21ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Decode and print a ARM register name */ 22ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengstatic char * decodeRegList(int vector, char *buf) 23ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 24ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int i; 25ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng bool printed = false; 26ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng buf[0] = 0; 27ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng for (i = 0; i < 8; i++, vector >>= 1) { 28ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (vector & 0x1) { 29ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (printed) { 30ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(buf + strlen(buf), ", r%d", i); 31ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 32ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng printed = true; 33ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(buf, "r%d", i); 34ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 35ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 36ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 37ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return buf; 38ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 39ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 407ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbeestatic int expandImmediate(int value) 417ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee{ 427ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee int mode = (value & 0xf00) >> 8; 437ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee u4 bits = value & 0xff; 447ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee switch(mode) { 457ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 0: 467ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return bits; 477ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 1: 487ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return (bits << 16) | bits; 497ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 2: 507ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return (bits << 24) | (bits << 8); 517ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 3: 527ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return (bits << 24) | (bits << 16) | (bits << 8) | bits; 537ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee default: 547ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee break; 557ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee } 567ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee bits = (bits | 0x80) << 24; 577ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return bits >> (((value & 0xf80) >> 7) - 8); 587ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee} 597ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee 60ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* 61ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Interpret a format string and build a string no longer than size 62ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * See format key in Assemble.c. 63ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */ 6489efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbeestatic void buildInsnString(char *fmt, ArmLIR *lir, char* buf, 65ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng unsigned char *baseAddr, int size) 66ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 67ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int i; 68ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char *bufEnd = &buf[size-1]; 69ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char *fmtEnd = &fmt[strlen(fmt)]; 70ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char tbuf[256]; 71ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char nc; 72ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng while (fmt < fmtEnd) { 73ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int operand; 74ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (*fmt == '!') { 75ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng fmt++; 76ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng assert(fmt < fmtEnd); 77ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng nc = *fmt++; 78ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (nc=='!') { 79ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf, "!"); 80ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 81ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng assert(fmt < fmtEnd); 82270c1d64a192341be842f46734054c692bac061eBill Buzbee assert((unsigned)(nc-'0') < 4); 83ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng operand = lir->operands[nc-'0']; 84ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng switch(*fmt++) { 85a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee case 'b': 86a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf,"0000"); 87a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee for (i=3; i>= 0; i--) { 88a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee tbuf[i] += operand & 1; 89a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee operand >>= 1; 90a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee } 91a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee break; 92270c1d64a192341be842f46734054c692bac061eBill Buzbee case 'n': 93270c1d64a192341be842f46734054c692bac061eBill Buzbee operand = ~expandImmediate(operand); 94270c1d64a192341be842f46734054c692bac061eBill Buzbee sprintf(tbuf,"%d [0x%x]", operand, operand); 95270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 967ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 'm': 977ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee operand = expandImmediate(operand); 987ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee sprintf(tbuf,"%d [0x%x]", operand, operand); 997ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee break; 1009727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee case 's': 1019727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee sprintf(tbuf,"s%d",operand & FP_REG_MASK); 1029727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee break; 1039727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee case 'S': 1049727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee sprintf(tbuf,"d%d",(operand & FP_REG_MASK) >> 1); 1059727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee break; 106ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'h': 107ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%04x", operand); 108ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1097ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 'M': 110ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'd': 111ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%d", operand); 112ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 113ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'E': 114ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%d", operand*4); 115ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 116ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'F': 117ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%d", operand*2); 118ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 119ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'c': 120ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng switch (operand) { 1211465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondEq: 122a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "eq"); 123ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1241465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondNe: 125a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "ne"); 126ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1271465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondLt: 128a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "lt"); 129ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1301465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondGe: 131a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "ge"); 132ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1331465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondGt: 134a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "gt"); 135ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1361465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondLe: 137a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "le"); 138ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1391465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondCs: 140a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "cs"); 141ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1421465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondMi: 143a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "mi"); 1447ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee break; 145ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng default: 146ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf, ""); 147ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 148ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 149ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 150ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 't': 151ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"0x%08x", 152ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng (int) baseAddr + lir->generic.offset + 4 + 153ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng (operand << 1)); 154ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 155ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'u': { 156ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int offset_1 = lir->operands[0]; 157ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int offset_2 = NEXT_LIR(lir)->operands[0]; 158ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng intptr_t target = 159ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ((((intptr_t) baseAddr + lir->generic.offset + 4) & 160ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) & 161ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 0xfffffffc; 162ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf, "%p", (void *) target); 163ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 164ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 165ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 166ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Nothing to print for BLX_2 */ 167ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'v': 168ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf, "see above"); 169ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 170ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'R': 171ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng decodeRegList(operand, tbuf); 172ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 173ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng default: 174ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf,"DecodeError"); 175ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 176ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 177ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (buf+strlen(tbuf) <= bufEnd) { 178ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(buf, tbuf); 179ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng buf += strlen(tbuf); 180ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 181ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 182ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 183ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 184ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 185ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *buf++ = *fmt++; 186ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 187ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (buf == bufEnd) 188ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 189ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 190ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *buf = 0; 191ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 192ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 193d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Chengvoid dvmDumpResourceMask(LIR *lir, u8 mask, const char *prefix) 194d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng{ 195d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng char buf[256]; 196d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng buf[0] = 0; 197d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng ArmLIR *armLIR = (ArmLIR *) lir; 198d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 199d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask == ENCODE_ALL) { 200d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcpy(buf, "all"); 201d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } else { 202d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng char num[8]; 203d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng int i; 204d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 205d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng for (i = 0; i < kRegEnd; i++) { 206d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask & (1ULL << i)) { 207d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng sprintf(num, "%d ", i); 208d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcat(buf, num); 209d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 210d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 211d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 212d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask & ENCODE_CCODE) { 213d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcat(buf, "cc "); 214d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 215d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask & ENCODE_FP_STATUS) { 216d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcat(buf, "fpcc "); 217d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 218d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (armLIR && (mask & ENCODE_DALVIK_REG)) { 219d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng sprintf(buf + strlen(buf), "dr%d%s", armLIR->aliasInfo & 0xffff, 220d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng (armLIR->aliasInfo & 0x80000000) ? "(+1)" : ""); 221d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 222d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 223d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (buf[0]) { 224d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng LOGD("%s: %s", prefix, buf); 225d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 226d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng} 227d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 228d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng/* 229d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng * Debugging macros 230d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng */ 231d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng#define DUMP_RESOURCE_MASK(X) 232d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng#define DUMP_SSA_REP(X) 233d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 234ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Pretty-print a LIR instruction */ 235d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Chengvoid dvmDumpLIRInsn(LIR *arg, unsigned char *baseAddr) 236ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 23789efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee ArmLIR *lir = (ArmLIR *) arg; 238ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char buf[256]; 239ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char opName[256]; 240ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int offset = lir->generic.offset; 241ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int dest = lir->operands[0]; 242ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng u2 *cPtr = (u2*)baseAddr; 243d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng const bool dumpNop = false; 244d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 245ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Handle pseudo-ops individually, and all regular insns as a group */ 246ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng switch(lir->opCode) { 247cec26f6ae3347d5ab3d60de02caca2e47151c6b2Ben Cheng case kArmChainingCellBottom: 248cec26f6ae3347d5ab3d60de02caca2e47151c6b2Ben Cheng LOGD("-------- end of chaining cells (0x%04x)\n", offset); 249cec26f6ae3347d5ab3d60de02caca2e47151c6b2Ben Cheng break; 2501465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoBarrier: 251d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng LOGD("-------- BARRIER"); 252dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng break; 2531465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoExtended: 2544238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng /* intentional fallthrough */ 2551465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoSSARep: 256d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng DUMP_SSA_REP(LOGD("-------- %s\n", (char *) dest)); 2574238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng break; 2581465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoTargetLabel: 259ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 2601465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case ARM_PSEUDO_kChainingCellBackwardBranch: 2614238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng LOGD("-------- chaining cell (backward branch): 0x%04x\n", dest); 2624238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng break; 2631465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case ARM_PSEUDO_kChainingCellNormal: 2641efc9c5e4c5c4c2fccde18e5771c68d064c33bd3Ben Cheng LOGD("-------- chaining cell (normal): 0x%04x\n", dest); 265ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 2661465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case ARM_PSEUDO_kChainingCellHot: 2671efc9c5e4c5c4c2fccde18e5771c68d064c33bd3Ben Cheng LOGD("-------- chaining cell (hot): 0x%04x\n", dest); 268ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 2691465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case ARM_PSEUDO_kChainingCellInvokePredicted: 27038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng LOGD("-------- chaining cell (predicted)\n"); 27138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng break; 2721465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case ARM_PSEUDO_kChainingCellInvokeSingleton: 27338329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng LOGD("-------- chaining cell (invoke singleton): %s/%p\n", 274ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ((Method *)dest)->name, 275ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ((Method *)dest)->insns); 276ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 2771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case ARM_PSEUDO_kEntryBlock: 2784238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng LOGD("-------- entry offset: 0x%04x\n", dest); 27997319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao break; 2801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case ARM_PSEUDO_kDalvikByteCode_BOUNDARY: 281ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("-------- dalvik offset: 0x%04x @ %s\n", dest, 282ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng (char *) lir->operands[1]); 283ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 2841465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case ARM_PSEUDO_kExitBlock: 2854238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng LOGD("-------- exit offset: 0x%04x\n", dest); 2864238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng break; 2871465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoPseudoAlign4: 288ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("%p (%04x): .align4\n", baseAddr + offset, offset); 289ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 2901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case ARM_PSEUDO_kPCReconstruction_CELL: 291ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("-------- reconstruct dalvik PC : 0x%04x @ +0x%04x\n", dest, 292ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng lir->operands[1]); 293ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 2941465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case ARM_PSEUDO_kPCReconstruction_BLOCK_LABEL: 295ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Do nothing */ 296ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 2971465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoEHBlockLabel: 298ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("Exception_Handling:\n"); 299ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 3001465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoNormalBlockLabel: 301ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("L%#06x:\n", dest); 302ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 303ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng default: 304d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (lir->isNop && !dumpNop) { 305e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng break; 306e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng } 307ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng buildInsnString(EncodingMap[lir->opCode].name, lir, opName, 308ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng baseAddr, 256); 309ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng buildInsnString(EncodingMap[lir->opCode].fmt, lir, buf, baseAddr, 310ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 256); 311d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng LOGD("%p (%04x): %-8s%s%s\n", 312d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng baseAddr + offset, offset, opName, buf, 313d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng lir->isNop ? "(nop)" : ""); 314ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 315ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 316d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 317d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (lir->useMask && (!lir->isNop || dumpNop)) { 318d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng DUMP_RESOURCE_MASK(dvmDumpResourceMask((LIR *) lir, 319d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng lir->useMask, "use")); 320d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 321d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (lir->defMask && (!lir->isNop || dumpNop)) { 322d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng DUMP_RESOURCE_MASK(dvmDumpResourceMask((LIR *) lir, 323d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng lir->defMask, "def")); 324d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 325ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 326ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 327ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Dump instructions and constant pool contents */ 328ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengvoid dvmCompilerCodegenDump(CompilationUnit *cUnit) 329ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 330ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("Dumping LIR insns\n"); 331ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LIR *lirInsn; 33289efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee ArmLIR *armLIR; 333ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 334ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("installed code is at %p\n", cUnit->baseAddr); 335ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("total size is %d bytes\n", cUnit->totalSize); 336ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng for (lirInsn = cUnit->firstLIRInsn; lirInsn; lirInsn = lirInsn->next) { 337d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng dvmDumpLIRInsn(lirInsn, cUnit->baseAddr); 338ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 339ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng for (lirInsn = cUnit->wordList; lirInsn; lirInsn = lirInsn->next) { 34089efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee armLIR = (ArmLIR *) lirInsn; 341ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("%p (%04x): .word (0x%x)\n", 342dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng (char*)cUnit->baseAddr + armLIR->generic.offset, 343dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng armLIR->generic.offset, 344ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng armLIR->operands[0]); 345ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 346ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 347