ArchUtility.cpp revision 18c990ebab4475335a5b94ac6077d3482b6875b9
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 */ 2818c990ebab4475335a5b94ac6077d3482b6875b9Ben Chengstatic char * decodeRegList(ArmOpcode opcode, int vector, char *buf) 29ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 30ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int i; 31ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng bool printed = false; 32ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng buf[0] = 0; 3318c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng for (i = 0; i < 16; i++, vector >>= 1) { 34ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (vector & 0x1) { 3518c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng int regId = i; 3618c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng if (opcode == kThumbPush && i == 8) { 3718c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng regId = rlr; 3818c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } else if (opcode == kThumbPop && i == 8) { 3918c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng regId = rpc; 4018c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng } 41ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (printed) { 4218c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng sprintf(buf + strlen(buf), ", r%d", regId); 43ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 44ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng printed = true; 4518c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng sprintf(buf, "r%d", regId); 46ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 47ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 48ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 49ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng return buf; 50ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 51ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 527ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbeestatic int expandImmediate(int value) 537ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee{ 547ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee int mode = (value & 0xf00) >> 8; 557ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee u4 bits = value & 0xff; 567ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee switch(mode) { 577ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 0: 587ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return bits; 597ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 1: 607ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return (bits << 16) | bits; 617ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 2: 627ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return (bits << 24) | (bits << 8); 637ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 3: 647ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return (bits << 24) | (bits << 16) | (bits << 8) | bits; 657ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee default: 667ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee break; 677ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee } 687ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee bits = (bits | 0x80) << 24; 697ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee return bits >> (((value & 0xf80) >> 7) - 8); 707ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee} 717ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee 72ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* 73ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * Interpret a format string and build a string no longer than size 74ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng * See format key in Assemble.c. 75ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng */ 7689efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbeestatic void buildInsnString(char *fmt, ArmLIR *lir, char* buf, 77ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng unsigned char *baseAddr, int size) 78ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 79ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int i; 80ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char *bufEnd = &buf[size-1]; 81ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char *fmtEnd = &fmt[strlen(fmt)]; 82ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char tbuf[256]; 83ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee char *name; 84ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char nc; 85ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng while (fmt < fmtEnd) { 86ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int operand; 87ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (*fmt == '!') { 88ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng fmt++; 89ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng assert(fmt < fmtEnd); 90ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng nc = *fmt++; 91ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (nc=='!') { 92ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf, "!"); 93ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 94ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng assert(fmt < fmtEnd); 95270c1d64a192341be842f46734054c692bac061eBill Buzbee assert((unsigned)(nc-'0') < 4); 96ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng operand = lir->operands[nc-'0']; 97ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng switch(*fmt++) { 9814f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee case 'H': 9914f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee if (operand != 0) { 10014f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee sprintf(tbuf, ", %s %d",shiftNames[operand & 0x3], 10114f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee operand >> 2); 10214f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee } else { 10314f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee strcpy(tbuf,""); 10414f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee } 10514f711ba6ffea52d6000e7d442d01b684bbe7f97buzbee break; 106ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case 'B': 107ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee switch (operand) { 108ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kSY: 109ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "sy"; 110ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 111ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kST: 112ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "st"; 113ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 114ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kISH: 115ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "ish"; 116ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 117ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kISHST: 118ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "ishst"; 119ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 120ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kNSH: 121ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "nsh"; 122ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 123ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee case kNSHST: 124ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "shst"; 125ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 126ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee default: 127ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee name = "DecodeError"; 128ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 129ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee } 130ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee strcpy(tbuf, name); 131ecf8f6ede2c00350a36297dd7427afff9d9cb154buzbee break; 132a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee case 'b': 133a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf,"0000"); 134a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee for (i=3; i>= 0; i--) { 135a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee tbuf[i] += operand & 1; 136a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee operand >>= 1; 137a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee } 138a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee break; 139270c1d64a192341be842f46734054c692bac061eBill Buzbee case 'n': 140270c1d64a192341be842f46734054c692bac061eBill Buzbee operand = ~expandImmediate(operand); 141270c1d64a192341be842f46734054c692bac061eBill Buzbee sprintf(tbuf,"%d [0x%x]", operand, operand); 142270c1d64a192341be842f46734054c692bac061eBill Buzbee break; 1437ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 'm': 1447ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee operand = expandImmediate(operand); 1457ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee sprintf(tbuf,"%d [0x%x]", operand, operand); 1467ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee break; 1479727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee case 's': 1489727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee sprintf(tbuf,"s%d",operand & FP_REG_MASK); 1499727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee break; 1509727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee case 'S': 1519727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee sprintf(tbuf,"d%d",(operand & FP_REG_MASK) >> 1); 1529727c3de12ab9daed0d92f6da2f5c0b0169e698dBill Buzbee break; 153ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'h': 154ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%04x", operand); 155ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1567ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee case 'M': 157ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'd': 158ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%d", operand); 159ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 160ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'E': 161ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%d", operand*4); 162ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 163ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'F': 164ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"%d", operand*2); 165ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 166ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'c': 167ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng switch (operand) { 1681465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondEq: 169a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "eq"); 170ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1711465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondNe: 172a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "ne"); 173ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1741465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondLt: 175a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "lt"); 176ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1771465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondGe: 178a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "ge"); 179ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1801465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondGt: 181a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "gt"); 182ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1831465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondLe: 184a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "le"); 185ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1861465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondCs: 187a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "cs"); 188ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 1891465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmCondMi: 190a4a7f0708e75eefae8cf9fff3f9e15699f7881beBill Buzbee strcpy(tbuf, "mi"); 1917ea0f64d067cd8a2213c2c04a3291335c34d9602Bill Buzbee break; 192ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng default: 193ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf, ""); 194ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 195ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 196ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 197ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 't': 198ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf,"0x%08x", 199ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng (int) baseAddr + lir->generic.offset + 4 + 200ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng (operand << 1)); 201ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 202ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'u': { 203ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int offset_1 = lir->operands[0]; 204ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int offset_2 = NEXT_LIR(lir)->operands[0]; 205ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng intptr_t target = 206ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ((((intptr_t) baseAddr + lir->generic.offset + 4) & 207ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) & 208ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 0xfffffffc; 209ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng sprintf(tbuf, "%p", (void *) target); 210ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 211ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 212ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 213ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Nothing to print for BLX_2 */ 214ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'v': 215ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf, "see above"); 216ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 217ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng case 'R': 21818c990ebab4475335a5b94ac6077d3482b6875b9Ben Cheng decodeRegList(lir->opcode, operand, tbuf); 219ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 220ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng default: 221ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(tbuf,"DecodeError"); 222ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 223ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 224ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (buf+strlen(tbuf) <= bufEnd) { 225ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng strcpy(buf, tbuf); 226ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng buf += strlen(tbuf); 227ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 228ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 229ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 230ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 231ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } else { 232ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *buf++ = *fmt++; 233ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 234ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng if (buf == bufEnd) 235ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 236ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 237ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng *buf = 0; 238ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 239ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 240d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Chengvoid dvmDumpResourceMask(LIR *lir, u8 mask, const char *prefix) 241d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng{ 242d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng char buf[256]; 243d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng buf[0] = 0; 244d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng ArmLIR *armLIR = (ArmLIR *) lir; 245d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 246d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask == ENCODE_ALL) { 247d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcpy(buf, "all"); 248d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } else { 249d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng char num[8]; 250d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng int i; 251d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 252d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng for (i = 0; i < kRegEnd; i++) { 253d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask & (1ULL << i)) { 254d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng sprintf(num, "%d ", i); 255d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcat(buf, num); 256d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 257d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 258d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 259d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask & ENCODE_CCODE) { 260d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcat(buf, "cc "); 261d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 262d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (mask & ENCODE_FP_STATUS) { 263d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng strcat(buf, "fpcc "); 264d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 265d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (armLIR && (mask & ENCODE_DALVIK_REG)) { 266d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng sprintf(buf + strlen(buf), "dr%d%s", armLIR->aliasInfo & 0xffff, 267d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng (armLIR->aliasInfo & 0x80000000) ? "(+1)" : ""); 268d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 269d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 270d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (buf[0]) { 271d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng LOGD("%s: %s", prefix, buf); 272d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 273d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng} 274d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 275d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng/* 276d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng * Debugging macros 277d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng */ 278d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng#define DUMP_RESOURCE_MASK(X) 279d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng#define DUMP_SSA_REP(X) 280d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 281ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Pretty-print a LIR instruction */ 282d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Chengvoid dvmDumpLIRInsn(LIR *arg, unsigned char *baseAddr) 283ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 28489efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee ArmLIR *lir = (ArmLIR *) arg; 285ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char buf[256]; 286ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng char opName[256]; 287ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int offset = lir->generic.offset; 288ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng int dest = lir->operands[0]; 289d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng const bool dumpNop = false; 290d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 291ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Handle pseudo-ops individually, and all regular insns as a group */ 2929a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein switch(lir->opcode) { 293cec26f6ae3347d5ab3d60de02caca2e47151c6b2Ben Cheng case kArmChainingCellBottom: 294cec26f6ae3347d5ab3d60de02caca2e47151c6b2Ben Cheng LOGD("-------- end of chaining cells (0x%04x)\n", offset); 295cec26f6ae3347d5ab3d60de02caca2e47151c6b2Ben Cheng break; 2961465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoBarrier: 297d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng LOGD("-------- BARRIER"); 298dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng break; 2991465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoExtended: 3007a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng LOGD("-------- %s\n", (char *) dest); 3017a2697d327936e20ef5484f7819e2e4bf91c891fBen Cheng break; 3021465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoSSARep: 303d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng DUMP_SSA_REP(LOGD("-------- %s\n", (char *) dest)); 3044238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng break; 3051465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoTargetLabel: 306ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 307a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoChainingCellBackwardBranch: 3084238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng LOGD("-------- chaining cell (backward branch): 0x%04x\n", dest); 3094238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng break; 310a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoChainingCellNormal: 3111efc9c5e4c5c4c2fccde18e5771c68d064c33bd3Ben Cheng LOGD("-------- chaining cell (normal): 0x%04x\n", dest); 312ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 313a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoChainingCellHot: 3141efc9c5e4c5c4c2fccde18e5771c68d064c33bd3Ben Cheng LOGD("-------- chaining cell (hot): 0x%04x\n", dest); 315ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 316a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoChainingCellInvokePredicted: 31738329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng LOGD("-------- chaining cell (predicted)\n"); 31838329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng break; 319a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoChainingCellInvokeSingleton: 32038329f5678fd7a4879528b02a0ab60322d38a897Ben Cheng LOGD("-------- chaining cell (invoke singleton): %s/%p\n", 321ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ((Method *)dest)->name, 322ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng ((Method *)dest)->insns); 323ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 324a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoEntryBlock: 3254238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng LOGD("-------- entry offset: 0x%04x\n", dest); 32697319a8a234e9fe1cf90ca39aa6eca37d729afd5Jeff Hao break; 327a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoDalvikByteCodeBoundary: 328ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("-------- dalvik offset: 0x%04x @ %s\n", dest, 329ccd6c0102d1f898aaea1c94761167fdd083b5275Ben Cheng (char *) lir->operands[1]); 330ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 331a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoExitBlock: 3324238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng LOGD("-------- exit offset: 0x%04x\n", dest); 3334238ec2ad1ace5103b2206a483f5f03d2e96c476Ben Cheng break; 3341465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoPseudoAlign4: 335ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("%p (%04x): .align4\n", baseAddr + offset, offset); 336ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 337a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoPCReconstructionCell: 338ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("-------- reconstruct dalvik PC : 0x%04x @ +0x%04x\n", dest, 339ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng lir->operands[1]); 340ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 341a497359afa1abe4c5780c8799c6fe0edab551c2dBen Cheng case kArmPseudoPCReconstructionBlockLabel: 342ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng /* Do nothing */ 343ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 3441465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoEHBlockLabel: 345ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("Exception_Handling:\n"); 346ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 3471465db5ee2d3c4c4dcc8e017a294172e858765cbBill Buzbee case kArmPseudoNormalBlockLabel: 348ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("L%#06x:\n", dest); 349ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 350ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng default: 351d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (lir->isNop && !dumpNop) { 352e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng break; 353e9695e5d281ad8bfbe3091e825befbedfc1b2007Ben Cheng } 3549a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein buildInsnString(EncodingMap[lir->opcode].name, lir, opName, 355ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng baseAddr, 256); 3569a1f81699cc05b58378ffb9aadb4e97677943791Dan Bornstein buildInsnString(EncodingMap[lir->opcode].fmt, lir, buf, baseAddr, 357ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 256); 358d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng LOGD("%p (%04x): %-8s%s%s\n", 359d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng baseAddr + offset, offset, opName, buf, 360d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng lir->isNop ? "(nop)" : ""); 361ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng break; 362ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 363d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng 364d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (lir->useMask && (!lir->isNop || dumpNop)) { 365d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng DUMP_RESOURCE_MASK(dvmDumpResourceMask((LIR *) lir, 366d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng lir->useMask, "use")); 367d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 368d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng if (lir->defMask && (!lir->isNop || dumpNop)) { 369d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng DUMP_RESOURCE_MASK(dvmDumpResourceMask((LIR *) lir, 370d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng lir->defMask, "def")); 371d7d426a1d746f70edeaeccf77886f3ad8298e28cBen Cheng } 372ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 373ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 374ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng/* Dump instructions and constant pool contents */ 375ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Chengvoid dvmCompilerCodegenDump(CompilationUnit *cUnit) 376ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng{ 377ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("Dumping LIR insns\n"); 378ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LIR *lirInsn; 37989efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee ArmLIR *armLIR; 380ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng 381ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("installed code is at %p\n", cUnit->baseAddr); 382ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("total size is %d bytes\n", cUnit->totalSize); 383ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng for (lirInsn = cUnit->firstLIRInsn; lirInsn; lirInsn = lirInsn->next) { 384fc75f3ed87b55d625b6054e18645da5cbdba31c6Carl Shapiro dvmDumpLIRInsn(lirInsn, (unsigned char *) cUnit->baseAddr); 385ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 386ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng for (lirInsn = cUnit->wordList; lirInsn; lirInsn = lirInsn->next) { 38789efc3d632adfa076bd622369b1ad8e4b49cf20eBill Buzbee armLIR = (ArmLIR *) lirInsn; 388ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng LOGD("%p (%04x): .word (0x%x)\n", 389dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng (char*)cUnit->baseAddr + armLIR->generic.offset, 390dcf3e5d43a1831a166f70cb9e0694cd4b0b356b0Ben Cheng armLIR->generic.offset, 391ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng armLIR->operands[0]); 392ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng } 393ba4fc8bfc1bccae048403bd1cea3b869dca61dd7Ben Cheng} 39413fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbee 39513fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbee/* Target-specific cache flushing */ 39613fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbeeint dvmCompilerCacheFlush(long start, long end, long flags) 39713fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbee{ 39813fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbee return cacheflush(start, end, flags); 39913fbc2e4bfa04cce8e181ac37d7f2b13a54aa037buzbee} 400