ArchUtility.cpp revision 13fbc2e4bfa04cce8e181ac37d7f2b13a54aa037
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" 18df4daaf8f41e3dcaa8221f54273338160dd43138Dan Bornstein#include "libdex/DexOpcodes.h" 1989efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee#include "ArmLIR.h" 20ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 2114f711ba6ffea52d6000e7d442d01b684bbe7f97buzbeestatic char *shiftNames[4] = { 2214f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee "lsl", 2314f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee "lsr", 2414f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee "asr", 2514f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee "ror"}; 2614f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee 27ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Decode and print a ARM register name */ 28ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengstatic char * decodeRegList(int vector, char *buf) 29ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 30ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int i; 31ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng bool printed = false; 32ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng buf[0] = 0; 33ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng for (i = 0; i < 8; i++, vector >>= 1) { 34ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (vector & 0x1) { 35ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (printed) { 36ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(buf + strlen(buf), ", r%d", i); 37ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 38ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng printed = true; 39ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(buf, "r%d", i); 40ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 41ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 42ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 43ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return buf; 44ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 45ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 467ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbeestatic int expandImmediate(int value) 477ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee{ 487ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee int mode = (value & 0xf00) >> 8; 497ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee u4 bits = value & 0xff; 507ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee switch(mode) { 517ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 0: 527ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return bits; 537ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 1: 547ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return (bits << 16) | bits; 557ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 2: 567ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return (bits << 24) | (bits << 8); 577ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 3: 587ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return (bits << 24) | (bits << 16) | (bits << 8) | bits; 597ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee default: 607ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee break; 617ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee } 627ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee bits = (bits | 0x80) << 24; 637ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return bits >> (((value & 0xf80) >> 7) - 8); 647ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee} 657ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee 66ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* 67ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Interpret a format string and build a string no longer than size 68ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * See format key in Assemble.c. 69ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */ 7089efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbeestatic void buildInsnString(char *fmt, ArmLIR *lir, char* buf, 71ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng unsigned char *baseAddr, int size) 72ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 73ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int i; 74ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char *bufEnd = &buf[size-1]; 75ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char *fmtEnd = &fmt[strlen(fmt)]; 76ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char tbuf[256]; 77ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee char *name; 78ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char nc; 79ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng while (fmt < fmtEnd) { 80ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int operand; 81ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (*fmt == '!') { 82ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng fmt++; 83ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng assert(fmt < fmtEnd); 84ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng nc = *fmt++; 85ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (nc=='!') { 86ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf, "!"); 87ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 88ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng assert(fmt < fmtEnd); 89270c1d64a192341be842f46734054c692bac061eBill Buzbee assert((unsigned)(nc-'0') < 4); 90ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng operand = lir->operands[nc-'0']; 91ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng switch(*fmt++) { 9214f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee case 'H': 9314f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee if (operand != 0) { 9414f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee sprintf(tbuf, ", %s %d",shiftNames[operand & 0x3], 9514f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee operand >> 2); 9614f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee } else { 9714f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee strcpy(tbuf,""); 9814f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee } 9914f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee break; 100ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case 'B': 101ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee switch (operand) { 102ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kSY: 103ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "sy"; 104ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 105ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kST: 106ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "st"; 107ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 108ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kISH: 109ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "ish"; 110ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 111ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kISHST: 112ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "ishst"; 113ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 114ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kNSH: 115ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "nsh"; 116ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 117ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kNSHST: 118ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "shst"; 119ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 120ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee default: 121ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "DecodeError"; 122ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 123ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee } 124ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee strcpy(tbuf, name); 125ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 126a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee case 'b': 127a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf,"0000"); 128a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee for (i=3; i>= 0; i--) { 129a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee tbuf[i] += operand & 1; 130a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee operand >>= 1; 131a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee } 132a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee break; 133270c1d64a192341be842f46734054c692bac061eBill Buzbee case 'n': 134270c1d64a192341be842f46734054c692bac061eBill Buzbee operand = ~expandImmediate(operand); 135270c1d64a192341be842f46734054c692bac061eBill Buzbee sprintf(tbuf,"%d [0x%x]", operand, operand); 136270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 1377ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 'm': 1387ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee operand = expandImmediate(operand); 1397ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee sprintf(tbuf,"%d [0x%x]", operand, operand); 1407ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee break; 1419727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee case 's': 1429727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee sprintf(tbuf,"s%d",operand & FP_REG_MASK); 1439727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee break; 1449727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee case 'S': 1459727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee sprintf(tbuf,"d%d",(operand & FP_REG_MASK) >> 1); 1469727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee break; 147ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'h': 148ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%04x", operand); 149ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1507ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 'M': 151ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'd': 152ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%d", operand); 153ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 154ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'E': 155ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%d", operand*4); 156ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 157ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'F': 158ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%d", operand*2); 159ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 160ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'c': 161ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng switch (operand) { 1621465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondEq: 163a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "eq"); 164ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1651465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondNe: 166a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "ne"); 167ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondLt: 169a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "lt"); 170ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondGe: 172a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "ge"); 173ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondGt: 175a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "gt"); 176ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondLe: 178a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "le"); 179ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondCs: 181a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "cs"); 182ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondMi: 184a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "mi"); 1857ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee break; 186ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng default: 187ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf, ""); 188ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 189ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 190ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 191ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 't': 192ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"0x%08x", 193ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng (int) baseAddr + lir->generic.offset + 4 + 194ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng (operand << 1)); 195ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 196ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'u': { 197ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int offset_1 = lir->operands[0]; 198ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int offset_2 = NEXT_LIR(lir)->operands[0]; 199ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng intptr_t target = 200ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ((((intptr_t) baseAddr + lir->generic.offset + 4) & 201ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) & 202ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 0xfffffffc; 203ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf, "%p", (void *) target); 204ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 205ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 206ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 207ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Nothing to print for BLX_2 */ 208ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'v': 209ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf, "see above"); 210ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 211ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'R': 212ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng decodeRegList(operand, tbuf); 213ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 214ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng default: 215ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf,"DecodeError"); 216ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 217ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 218ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (buf+strlen(tbuf) <= bufEnd) { 219ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(buf, tbuf); 220ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng buf += strlen(tbuf); 221ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 222ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 223ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 224ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 225ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 226ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *buf++ = *fmt++; 227ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 228ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (buf == bufEnd) 229ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 230ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 231ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *buf = 0; 232ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 233ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 234d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Chengvoid dvmDumpResourceMask(LIR *lir, u8 mask, const char *prefix) 235d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng{ 236d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng char buf[256]; 237d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng buf[0] = 0; 238d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng ArmLIR *armLIR = (ArmLIR *) lir; 239d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 240d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask == ENCODE_ALL) { 241d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcpy(buf, "all"); 242d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } else { 243d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng char num[8]; 244d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng int i; 245d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 246d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng for (i = 0; i < kRegEnd; i++) { 247d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask & (1ULL << i)) { 248d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng sprintf(num, "%d ", i); 249d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcat(buf, num); 250d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 251d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 252d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 253d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask & ENCODE_CCODE) { 254d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcat(buf, "cc "); 255d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 256d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask & ENCODE_FP_STATUS) { 257d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcat(buf, "fpcc "); 258d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 259d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (armLIR && (mask & ENCODE_DALVIK_REG)) { 260d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng sprintf(buf + strlen(buf), "dr%d%s", armLIR->aliasInfo & 0xffff, 261d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng (armLIR->aliasInfo & 0x80000000) ? "(+1)" : ""); 262d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 263d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 264d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (buf[0]) { 265d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng LOGD("%s: %s", prefix, buf); 266d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 267d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng} 268d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 269d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng/* 270d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng * Debugging macros 271d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng */ 272d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng#define DUMP_RESOURCE_MASK(X) 273d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng#define DUMP_SSA_REP(X) 274d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 275ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Pretty-print a LIR instruction */ 276d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Chengvoid dvmDumpLIRInsn(LIR *arg, unsigned char *baseAddr) 277ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 27889efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee ArmLIR *lir = (ArmLIR *) arg; 279ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char buf[256]; 280ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char opName[256]; 281ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int offset = lir->generic.offset; 282ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int dest = lir->operands[0]; 283d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng const bool dumpNop = false; 284d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 285ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Handle pseudo-ops individually, and all regular insns as a group */ 2869a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein switch(lir->opcode) { 287cec26f6ae3347d5ab3d60de02caca2e47151c6b2Ben Cheng case kArmChainingCellBottom: 288cec26f6ae3347d5ab3d60de02caca2e47151c6b2Ben Cheng LOGD("-------- end of chaining cells (0x%04x)\n", offset); 289cec26f6ae3347d5ab3d60de02caca2e47151c6b2Ben Cheng break; 2901465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoBarrier: 291d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng LOGD("-------- BARRIER"); 292dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng break; 2931465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoExtended: 2947a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng LOGD("-------- %s\n", (char *) dest); 2957a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng break; 2961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoSSARep: 297d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng DUMP_SSA_REP(LOGD("-------- %s\n", (char *) dest)); 2984238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng break; 2991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoTargetLabel: 300ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 301a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoChainingCellBackwardBranch: 3024238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng LOGD("-------- chaining cell (backward branch): 0x%04x\n", dest); 3034238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng break; 304a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoChainingCellNormal: 3051efc9c5e4c5c4c2fccde18e5771c68d064c33bd3Ben Cheng LOGD("-------- chaining cell (normal): 0x%04x\n", dest); 306ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 307a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoChainingCellHot: 3081efc9c5e4c5c4c2fccde18e5771c68d064c33bd3Ben Cheng LOGD("-------- chaining cell (hot): 0x%04x\n", dest); 309ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 310a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoChainingCellInvokePredicted: 31138329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng LOGD("-------- chaining cell (predicted)\n"); 31238329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng break; 313a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoChainingCellInvokeSingleton: 31438329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng LOGD("-------- chaining cell (invoke singleton): %s/%p\n", 315ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ((Method *)dest)->name, 316ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ((Method *)dest)->insns); 317ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 318a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoEntryBlock: 3194238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng LOGD("-------- entry offset: 0x%04x\n", dest); 32097319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao break; 321a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoDalvikByteCodeBoundary: 322ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("-------- dalvik offset: 0x%04x @ %s\n", dest, 323ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng (char *) lir->operands[1]); 324ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 325a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoExitBlock: 3264238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng LOGD("-------- exit offset: 0x%04x\n", dest); 3274238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng break; 3281465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoPseudoAlign4: 329ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("%p (%04x): .align4\n", baseAddr + offset, offset); 330ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 331a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoPCReconstructionCell: 332ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("-------- reconstruct dalvik PC : 0x%04x @ +0x%04x\n", dest, 333ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng lir->operands[1]); 334ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 335a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoPCReconstructionBlockLabel: 336ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Do nothing */ 337ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 3381465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoEHBlockLabel: 339ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("Exception_Handling:\n"); 340ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 3411465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoNormalBlockLabel: 342ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("L%#06x:\n", dest); 343ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 344ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng default: 345d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (lir->isNop && !dumpNop) { 346e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng break; 347e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng } 3489a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein buildInsnString(EncodingMap[lir->opcode].name, lir, opName, 349ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng baseAddr, 256); 3509a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein buildInsnString(EncodingMap[lir->opcode].fmt, lir, buf, baseAddr, 351ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 256); 352d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng LOGD("%p (%04x): %-8s%s%s\n", 353d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng baseAddr + offset, offset, opName, buf, 354d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng lir->isNop ? "(nop)" : ""); 355ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 356ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 357d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 358d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (lir->useMask && (!lir->isNop || dumpNop)) { 359d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng DUMP_RESOURCE_MASK(dvmDumpResourceMask((LIR *) lir, 360d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng lir->useMask, "use")); 361d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 362d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (lir->defMask && (!lir->isNop || dumpNop)) { 363d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng DUMP_RESOURCE_MASK(dvmDumpResourceMask((LIR *) lir, 364d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng lir->defMask, "def")); 365d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 366ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 367ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 368ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Dump instructions and constant pool contents */ 369ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengvoid dvmCompilerCodegenDump(CompilationUnit *cUnit) 370ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 371ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("Dumping LIR insns\n"); 372ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LIR *lirInsn; 37389efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee ArmLIR *armLIR; 374ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 375ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("installed code is at %p\n", cUnit->baseAddr); 376ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("total size is %d bytes\n", cUnit->totalSize); 377ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng for (lirInsn = cUnit->firstLIRInsn; lirInsn; lirInsn = lirInsn->next) { 378fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro dvmDumpLIRInsn(lirInsn, (unsigned char *) cUnit->baseAddr); 379ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 380ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng for (lirInsn = cUnit->wordList; lirInsn; lirInsn = lirInsn->next) { 38189efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee armLIR = (ArmLIR *) lirInsn; 382ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("%p (%04x): .word (0x%x)\n", 383dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng (char*)cUnit->baseAddr + armLIR->generic.offset, 384dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng armLIR->generic.offset, 385ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng armLIR->operands[0]); 386ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 387ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 38813fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbee 38913fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbee/* Target-specific cache flushing */ 39013fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbeeint dvmCompilerCacheFlush(long start, long end, long flags) 39113fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbee{ 39213fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbee return cacheflush(start, end, flags); 39313fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbee} 394