blob: ead9ff5cd815cb89de9b1fbfd6c76b9d7d990698 [file] [log] [blame]
buzbeee3acd072012-02-25 17:03:10 -08001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "../../CompilerInternals.h"
18#include "MipsLIR.h"
19#include "../Ralloc.h"
20
21#include <string>
22
23namespace art {
24
25/* For dumping instructions */
26#define MIPS_REG_COUNT 32
27static const char *mipsRegName[MIPS_REG_COUNT] = {
Bill Buzbeea114add2012-05-03 15:00:40 -070028 "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
29 "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
30 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
31 "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
buzbeee3acd072012-02-25 17:03:10 -080032};
33
34/*
35 * Interpret a format string and build a string no longer than size
36 * See format key in Assemble.c.
37 */
buzbee5de34942012-03-01 14:51:57 -080038std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr)
buzbeee3acd072012-02-25 17:03:10 -080039{
Bill Buzbeea114add2012-05-03 15:00:40 -070040 std::string buf;
41 int i;
42 const char *fmtEnd = &fmt[strlen(fmt)];
43 char tbuf[256];
44 char nc;
45 while (fmt < fmtEnd) {
46 int operand;
47 if (*fmt == '!') {
48 fmt++;
49 DCHECK_LT(fmt, fmtEnd);
50 nc = *fmt++;
51 if (nc=='!') {
52 strcpy(tbuf, "!");
53 } else {
54 DCHECK_LT(fmt, fmtEnd);
55 DCHECK_LT((unsigned)(nc-'0'), 4u);
56 operand = lir->operands[nc-'0'];
57 switch (*fmt++) {
58 case 'b':
59 strcpy(tbuf,"0000");
60 for (i=3; i>= 0; i--) {
61 tbuf[i] += operand & 1;
62 operand >>= 1;
63 }
64 break;
65 case 's':
66 sprintf(tbuf,"$f%d",operand & FP_REG_MASK);
67 break;
68 case 'S':
69 DCHECK_EQ(((operand & FP_REG_MASK) & 1), 0);
70 sprintf(tbuf,"$f%d",operand & FP_REG_MASK);
71 break;
72 case 'h':
73 sprintf(tbuf,"%04x", operand);
74 break;
75 case 'M':
76 case 'd':
77 sprintf(tbuf,"%d", operand);
78 break;
79 case 'D':
80 sprintf(tbuf,"%d", operand+1);
81 break;
82 case 'E':
83 sprintf(tbuf,"%d", operand*4);
84 break;
85 case 'F':
86 sprintf(tbuf,"%d", operand*2);
87 break;
88 case 't':
89 sprintf(tbuf,"0x%08x (L%p)", (int) baseAddr + lir->offset + 4 +
90 (operand << 2), lir->target);
91 break;
92 case 'T':
93 sprintf(tbuf,"0x%08x", (int) (operand << 2));
94 break;
95 case 'u': {
96 int offset_1 = lir->operands[0];
97 int offset_2 = NEXT_LIR(lir)->operands[0];
98 intptr_t target =
99 ((((intptr_t) baseAddr + lir->offset + 4) & ~3) +
100 (offset_1 << 21 >> 9) + (offset_2 << 1)) & 0xfffffffc;
101 sprintf(tbuf, "%p", (void *) target);
102 break;
103 }
buzbeee3acd072012-02-25 17:03:10 -0800104
Bill Buzbeea114add2012-05-03 15:00:40 -0700105 /* Nothing to print for BLX_2 */
106 case 'v':
107 strcpy(tbuf, "see above");
108 break;
109 case 'r':
110 DCHECK(operand >= 0 && operand < MIPS_REG_COUNT);
111 strcpy(tbuf, mipsRegName[operand]);
112 break;
113 case 'N':
114 // Placeholder for delay slot handling
115 strcpy(tbuf, "; nop");
116 break;
117 default:
118 strcpy(tbuf,"DecodeError");
119 break;
120 }
121 buf += tbuf;
122 }
123 } else {
124 buf += *fmt++;
buzbeee3acd072012-02-25 17:03:10 -0800125 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700126 }
127 return buf;
buzbeee3acd072012-02-25 17:03:10 -0800128}
129
buzbee408ad162012-06-06 16:45:18 -0700130// FIXME: need to redo resource maps for MIPS - fix this at that time
buzbeee3acd072012-02-25 17:03:10 -0800131void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix)
132{
Bill Buzbeea114add2012-05-03 15:00:40 -0700133 char buf[256];
134 buf[0] = 0;
135 LIR *mipsLIR = (LIR *) lir;
buzbeee3acd072012-02-25 17:03:10 -0800136
Bill Buzbeea114add2012-05-03 15:00:40 -0700137 if (mask == ENCODE_ALL) {
138 strcpy(buf, "all");
139 } else {
140 char num[8];
141 int i;
buzbeee3acd072012-02-25 17:03:10 -0800142
Bill Buzbeea114add2012-05-03 15:00:40 -0700143 for (i = 0; i < kRegEnd; i++) {
144 if (mask & (1ULL << i)) {
145 sprintf(num, "%d ", i);
146 strcat(buf, num);
147 }
buzbeee3acd072012-02-25 17:03:10 -0800148 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700149
150 if (mask & ENCODE_CCODE) {
151 strcat(buf, "cc ");
buzbeee3acd072012-02-25 17:03:10 -0800152 }
Bill Buzbeea114add2012-05-03 15:00:40 -0700153 if (mask & ENCODE_FP_STATUS) {
154 strcat(buf, "fpcc ");
155 }
156 /* Memory bits */
157 if (mipsLIR && (mask & ENCODE_DALVIK_REG)) {
158 sprintf(buf + strlen(buf), "dr%d%s", mipsLIR->aliasInfo & 0xffff,
159 (mipsLIR->aliasInfo & 0x80000000) ? "(+1)" : "");
160 }
161 if (mask & ENCODE_LITERAL) {
162 strcat(buf, "lit ");
163 }
164
165 if (mask & ENCODE_HEAP_REF) {
166 strcat(buf, "heap ");
167 }
168 if (mask & ENCODE_MUST_NOT_ALIAS) {
169 strcat(buf, "noalias ");
170 }
171 }
172 if (buf[0]) {
173 LOG(INFO) << prefix << ": " << buf;
174 }
buzbeee3acd072012-02-25 17:03:10 -0800175}
176
buzbeee3acd072012-02-25 17:03:10 -0800177} // namespace art