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