blob: 40188ce18187fa4dc1948cbcea0efe218cccfa6f [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] = {
28 "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"
32};
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{
40 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;
buzbeee3acd072012-02-25 17:03:10 -080088 case 't':
89 sprintf(tbuf,"0x%08x (L%p)",
buzbee5de34942012-03-01 14:51:57 -080090 (int) baseAddr + lir->offset + 4 +
buzbeee3acd072012-02-25 17:03:10 -080091 (operand << 2),
buzbee5de34942012-03-01 14:51:57 -080092 lir->target);
buzbeee3acd072012-02-25 17:03:10 -080093 break;
94 case 'T':
95 sprintf(tbuf,"0x%08x",
96 (int) (operand << 2));
97 break;
98 case 'u': {
99 int offset_1 = lir->operands[0];
100 int offset_2 = NEXT_LIR(lir)->operands[0];
101 intptr_t target =
buzbee5de34942012-03-01 14:51:57 -0800102 ((((intptr_t) baseAddr + lir->offset + 4) &
buzbeee3acd072012-02-25 17:03:10 -0800103 ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) &
104 0xfffffffc;
105 sprintf(tbuf, "%p", (void *) target);
106 break;
107 }
108
109 /* Nothing to print for BLX_2 */
110 case 'v':
111 strcpy(tbuf, "see above");
112 break;
113 case 'r':
114 DCHECK(operand >= 0 && operand < MIPS_REG_COUNT);
115 strcpy(tbuf, mipsRegName[operand]);
116 break;
buzbee82488f52012-03-02 08:20:26 -0800117 case 'N':
118 // Placeholder for delay slot handling
119 strcpy(tbuf, "; nop");
120 break;
buzbeee3acd072012-02-25 17:03:10 -0800121 default:
122 strcpy(tbuf,"DecodeError");
123 break;
124 }
125 buf += tbuf;
126 }
127 } else {
128 buf += *fmt++;
129 }
130 }
131 return buf;
132}
133
134// FIXME: need to redo resourse maps for MIPS - fix this at that time
135void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix)
136{
137 char buf[256];
138 buf[0] = 0;
buzbee5de34942012-03-01 14:51:57 -0800139 LIR *mipsLIR = (LIR *) lir;
buzbeee3acd072012-02-25 17:03:10 -0800140
141 if (mask == ENCODE_ALL) {
142 strcpy(buf, "all");
143 } else {
144 char num[8];
145 int i;
146
147 for (i = 0; i < kRegEnd; i++) {
148 if (mask & (1ULL << i)) {
149 sprintf(num, "%d ", i);
150 strcat(buf, num);
151 }
152 }
153
154 if (mask & ENCODE_CCODE) {
155 strcat(buf, "cc ");
156 }
157 if (mask & ENCODE_FP_STATUS) {
158 strcat(buf, "fpcc ");
159 }
160 /* Memory bits */
161 if (mipsLIR && (mask & ENCODE_DALVIK_REG)) {
162 sprintf(buf + strlen(buf), "dr%d%s", mipsLIR->aliasInfo & 0xffff,
163 (mipsLIR->aliasInfo & 0x80000000) ? "(+1)" : "");
164 }
165 if (mask & ENCODE_LITERAL) {
166 strcat(buf, "lit ");
167 }
168
169 if (mask & ENCODE_HEAP_REF) {
170 strcat(buf, "heap ");
171 }
172 if (mask & ENCODE_MUST_NOT_ALIAS) {
173 strcat(buf, "noalias ");
174 }
175 }
176 if (buf[0]) {
177 LOG(INFO) << prefix << ": " << buf;
178 }
179}
180
buzbeee3acd072012-02-25 17:03:10 -0800181} // namespace art