ArchUtility.cpp revision 13fbc2e4bfa04cce8e181ac37d7f2b13a54aa037
1f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project/*
2f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
3a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt *
4f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * you may not use this file except in compliance with the License.
6f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * You may obtain a copy of the License at
7f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *
8f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project *
10f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * See the License for the specific language governing permissions and
14f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project * limitations under the License.
15f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project */
16f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
17f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "../../CompilerInternals.h"
18f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "libdex/DexOpcodes.h"
19f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project#include "ArmLIR.h"
20f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
21f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatic char *shiftNames[4] = {
22f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project    "lsl",
23f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project    "lsr",
24f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project    "asr",
25f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project    "ror"};
26f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project
27f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project/* Decode and print a ARM register name */
28f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Projectstatic char * decodeRegList(int vector, char *buf)
29f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project{
30f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project    int i;
31f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project    bool printed = false;
32f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project    buf[0] = 0;
33a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt    for (i = 0; i < 8; i++, vector >>= 1) {
34f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project        if (vector & 0x1) {
35f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project            if (printed) {
36f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project                sprintf(buf + strlen(buf), ", r%d", i);
37e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt            } else {
38e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                printed = true;
39e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                sprintf(buf, "r%d", i);
40e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt            }
41e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        }
42e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    }
43e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    return buf;
44e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}
45e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
46e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic int expandImmediate(int value)
47e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{
48e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    int mode = (value & 0xf00) >> 8;
49e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    u4 bits = value & 0xff;
50e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    switch(mode) {
51e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        case 0:
52e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt            return bits;
53e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt       case 1:
54e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt            return (bits << 16) | bits;
55e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt       case 2:
56e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt            return (bits << 24) | (bits << 8);
57e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt       case 3:
58e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt            return (bits << 24) | (bits << 16) | (bits << 8) | bits;
59e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt      default:
60e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt            break;
61e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    }
62e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    bits = (bits | 0x80) << 24;
63e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    return bits >> (((value & 0xf80) >> 7) - 8);
64e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt}
65e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt
66e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt/*
67e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * Interpret a format string and build a string no longer than size
68e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt * See format key in Assemble.c.
69e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt */
70e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidtstatic void buildInsnString(char *fmt, ArmLIR *lir, char* buf,
71e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                            unsigned char *baseAddr, int size)
72e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt{
73e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    int i;
74e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    char *bufEnd = &buf[size-1];
75e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    char *fmtEnd = &fmt[strlen(fmt)];
76e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    char tbuf[256];
77e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    char *name;
78e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    char nc;
79e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt    while (fmt < fmtEnd) {
80e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        int operand;
81e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt        if (*fmt == '!') {
82e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt            fmt++;
83e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt            assert(fmt < fmtEnd);
84e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt            nc = *fmt++;
85a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt            if (nc=='!') {
86a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                strcpy(tbuf, "!");
87a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt            } else {
88a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt               assert(fmt < fmtEnd);
89a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt               assert((unsigned)(nc-'0') < 4);
90a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt               operand = lir->operands[nc-'0'];
91a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt               switch(*fmt++) {
92a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                   case 'H':
93a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                       if (operand != 0) {
94a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                           sprintf(tbuf, ", %s %d",shiftNames[operand & 0x3],
95a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                                   operand >> 2);
96a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                       } else {
97a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                           strcpy(tbuf,"");
98a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                       }
99a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                       break;
100a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                   case 'B':
101a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                       switch (operand) {
102a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                           case kSY:
103a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                               name = "sy";
104a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                               break;
105a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                           case kST:
106a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                               name = "st";
107a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                               break;
108a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                           case kISH:
109e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               name = "ish";
110e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               break;
111e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                           case kISHST:
112e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               name = "ishst";
113e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               break;
114e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                           case kNSH:
115e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               name = "nsh";
116e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               break;
117f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project                           case kNSHST:
118e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               name = "shst";
119e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               break;
120e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                           default:
121e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               name = "DecodeError";
122e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               break;
123e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       }
124e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       strcpy(tbuf, name);
125e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       break;
126e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                   case 'b':
127e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       strcpy(tbuf,"0000");
128e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       for (i=3; i>= 0; i--) {
129e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                           tbuf[i] += operand & 1;
130e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                           operand >>= 1;
131e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       }
132e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       break;
133e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                   case 'n':
134e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       operand = ~expandImmediate(operand);
135e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       sprintf(tbuf,"%d [0x%x]", operand, operand);
136e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       break;
137a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                   case 'm':
138a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                       operand = expandImmediate(operand);
139a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                       sprintf(tbuf,"%d [0x%x]", operand, operand);
140a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                       break;
141a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                   case 's':
142e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       sprintf(tbuf,"s%d",operand & FP_REG_MASK);
143f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project                       break;
144e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                   case 'S':
145e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       sprintf(tbuf,"d%d",(operand & FP_REG_MASK) >> 1);
146a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                       break;
147e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                   case 'h':
148e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       sprintf(tbuf,"%04x", operand);
149e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       break;
150e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                   case 'M':
151e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                   case 'd':
1520d3a47d979ac35a49b2a2da9e80e16bd37aab877repo sync                       sprintf(tbuf,"%d", operand);
153e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       break;
154e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                   case 'E':
155e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       sprintf(tbuf,"%d", operand*4);
156a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                       break;
157e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                   case 'F':
158e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       sprintf(tbuf,"%d", operand*2);
159e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       break;
160e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                   case 'c':
161e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                       switch (operand) {
162e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                           case kArmCondEq:
163e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               strcpy(tbuf, "eq");
164e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               break;
165e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                           case kArmCondNe:
166e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               strcpy(tbuf, "ne");
167e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               break;
168e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                           case kArmCondLt:
169e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               strcpy(tbuf, "lt");
170e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               break;
171e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                           case kArmCondGe:
172a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                               strcpy(tbuf, "ge");
173a3a2260384a906e1674c7498c2f479e9f37bc503Dmitry Shmidt                               break;
174e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                           case kArmCondGt:
175e86eee143ed21592f88a46623a81f71002430459Dmitry Shmidt                               strcpy(tbuf, "gt");
176f7c5421560640d23fc10803b9d59a9ff1d83e467The Android Open Source Project                               break;
177                           case kArmCondLe:
178                               strcpy(tbuf, "le");
179                               break;
180                           case kArmCondCs:
181                               strcpy(tbuf, "cs");
182                               break;
183                           case kArmCondMi:
184                               strcpy(tbuf, "mi");
185                               break;
186                           default:
187                               strcpy(tbuf, "");
188                               break;
189                       }
190                       break;
191                   case 't':
192                       sprintf(tbuf,"0x%08x",
193                               (int) baseAddr + lir->generic.offset + 4 +
194                               (operand << 1));
195                       break;
196                   case 'u': {
197                       int offset_1 = lir->operands[0];
198                       int offset_2 = NEXT_LIR(lir)->operands[0];
199                       intptr_t target =
200                           ((((intptr_t) baseAddr + lir->generic.offset + 4) &
201                            ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) &
202                           0xfffffffc;
203                       sprintf(tbuf, "%p", (void *) target);
204                       break;
205                    }
206
207                   /* Nothing to print for BLX_2 */
208                   case 'v':
209                       strcpy(tbuf, "see above");
210                       break;
211                   case 'R':
212                       decodeRegList(operand, tbuf);
213                       break;
214                   default:
215                       strcpy(tbuf,"DecodeError");
216                       break;
217               }
218               if (buf+strlen(tbuf) <= bufEnd) {
219                   strcpy(buf, tbuf);
220                   buf += strlen(tbuf);
221               } else {
222                   break;
223               }
224            }
225        } else {
226           *buf++ = *fmt++;
227        }
228        if (buf == bufEnd)
229            break;
230    }
231    *buf = 0;
232}
233
234void dvmDumpResourceMask(LIR *lir, u8 mask, const char *prefix)
235{
236    char buf[256];
237    buf[0] = 0;
238    ArmLIR *armLIR = (ArmLIR *) lir;
239
240    if (mask == ENCODE_ALL) {
241        strcpy(buf, "all");
242    } else {
243        char num[8];
244        int i;
245
246        for (i = 0; i < kRegEnd; i++) {
247            if (mask & (1ULL << i)) {
248                sprintf(num, "%d ", i);
249                strcat(buf, num);
250            }
251        }
252
253        if (mask & ENCODE_CCODE) {
254            strcat(buf, "cc ");
255        }
256        if (mask & ENCODE_FP_STATUS) {
257            strcat(buf, "fpcc ");
258        }
259        if (armLIR && (mask & ENCODE_DALVIK_REG)) {
260            sprintf(buf + strlen(buf), "dr%d%s", armLIR->aliasInfo & 0xffff,
261                    (armLIR->aliasInfo & 0x80000000) ? "(+1)" : "");
262        }
263    }
264    if (buf[0]) {
265        LOGD("%s: %s", prefix, buf);
266    }
267}
268
269/*
270 * Debugging macros
271 */
272#define DUMP_RESOURCE_MASK(X)
273#define DUMP_SSA_REP(X)
274
275/* Pretty-print a LIR instruction */
276void dvmDumpLIRInsn(LIR *arg, unsigned char *baseAddr)
277{
278    ArmLIR *lir = (ArmLIR *) arg;
279    char buf[256];
280    char opName[256];
281    int offset = lir->generic.offset;
282    int dest = lir->operands[0];
283    const bool dumpNop = false;
284
285    /* Handle pseudo-ops individually, and all regular insns as a group */
286    switch(lir->opcode) {
287        case kArmChainingCellBottom:
288            LOGD("-------- end of chaining cells (0x%04x)\n", offset);
289            break;
290        case kArmPseudoBarrier:
291            LOGD("-------- BARRIER");
292            break;
293        case kArmPseudoExtended:
294            LOGD("-------- %s\n", (char *) dest);
295            break;
296        case kArmPseudoSSARep:
297            DUMP_SSA_REP(LOGD("-------- %s\n", (char *) dest));
298            break;
299        case kArmPseudoTargetLabel:
300            break;
301        case kArmPseudoChainingCellBackwardBranch:
302            LOGD("-------- chaining cell (backward branch): 0x%04x\n", dest);
303            break;
304        case kArmPseudoChainingCellNormal:
305            LOGD("-------- chaining cell (normal): 0x%04x\n", dest);
306            break;
307        case kArmPseudoChainingCellHot:
308            LOGD("-------- chaining cell (hot): 0x%04x\n", dest);
309            break;
310        case kArmPseudoChainingCellInvokePredicted:
311            LOGD("-------- chaining cell (predicted)\n");
312            break;
313        case kArmPseudoChainingCellInvokeSingleton:
314            LOGD("-------- chaining cell (invoke singleton): %s/%p\n",
315                 ((Method *)dest)->name,
316                 ((Method *)dest)->insns);
317            break;
318        case kArmPseudoEntryBlock:
319            LOGD("-------- entry offset: 0x%04x\n", dest);
320            break;
321        case kArmPseudoDalvikByteCodeBoundary:
322            LOGD("-------- dalvik offset: 0x%04x @ %s\n", dest,
323                 (char *) lir->operands[1]);
324            break;
325        case kArmPseudoExitBlock:
326            LOGD("-------- exit offset: 0x%04x\n", dest);
327            break;
328        case kArmPseudoPseudoAlign4:
329            LOGD("%p (%04x): .align4\n", baseAddr + offset, offset);
330            break;
331        case kArmPseudoPCReconstructionCell:
332            LOGD("-------- reconstruct dalvik PC : 0x%04x @ +0x%04x\n", dest,
333                 lir->operands[1]);
334            break;
335        case kArmPseudoPCReconstructionBlockLabel:
336            /* Do nothing */
337            break;
338        case kArmPseudoEHBlockLabel:
339            LOGD("Exception_Handling:\n");
340            break;
341        case kArmPseudoNormalBlockLabel:
342            LOGD("L%#06x:\n", dest);
343            break;
344        default:
345            if (lir->isNop && !dumpNop) {
346                break;
347            }
348            buildInsnString(EncodingMap[lir->opcode].name, lir, opName,
349                            baseAddr, 256);
350            buildInsnString(EncodingMap[lir->opcode].fmt, lir, buf, baseAddr,
351                            256);
352            LOGD("%p (%04x): %-8s%s%s\n",
353                 baseAddr + offset, offset, opName, buf,
354                 lir->isNop ? "(nop)" : "");
355            break;
356    }
357
358    if (lir->useMask && (!lir->isNop || dumpNop)) {
359        DUMP_RESOURCE_MASK(dvmDumpResourceMask((LIR *) lir,
360                                               lir->useMask, "use"));
361    }
362    if (lir->defMask && (!lir->isNop || dumpNop)) {
363        DUMP_RESOURCE_MASK(dvmDumpResourceMask((LIR *) lir,
364                                               lir->defMask, "def"));
365    }
366}
367
368/* Dump instructions and constant pool contents */
369void dvmCompilerCodegenDump(CompilationUnit *cUnit)
370{
371    LOGD("Dumping LIR insns\n");
372    LIR *lirInsn;
373    ArmLIR *armLIR;
374
375    LOGD("installed code is at %p\n", cUnit->baseAddr);
376    LOGD("total size is %d bytes\n", cUnit->totalSize);
377    for (lirInsn = cUnit->firstLIRInsn; lirInsn; lirInsn = lirInsn->next) {
378        dvmDumpLIRInsn(lirInsn, (unsigned char *) cUnit->baseAddr);
379    }
380    for (lirInsn = cUnit->wordList; lirInsn; lirInsn = lirInsn->next) {
381        armLIR = (ArmLIR *) lirInsn;
382        LOGD("%p (%04x): .word (0x%x)\n",
383             (char*)cUnit->baseAddr + armLIR->generic.offset,
384             armLIR->generic.offset,
385             armLIR->operands[0]);
386    }
387}
388
389/* Target-specific cache flushing */
390int dvmCompilerCacheFlush(long start, long end, long flags)
391{
392    return cacheflush(start, end, flags);
393}
394